Diff for /loncom/interface/lonfeedback.pm between versions 1.126 and 1.158

version 1.126, 2004/09/15 06:17:11 version 1.158, 2005/04/07 07:34:52
Line 35  use Apache::lonmsg(); Line 35  use Apache::lonmsg();
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lontexconvert();  use Apache::lontexconvert();
 use Apache::lonlocal; # must not have ()  use Apache::lonlocal; # must not have ()
   use Apache::lonnet;
 use Apache::lonhtmlcommon();  use Apache::lonhtmlcommon();
   use Apache::lonnavmaps;
   use Apache::lonenc();
 use HTML::LCParser();  use HTML::LCParser();
 use Apache::lonspeller();  use Apache::lonspeller();
 use Cwd;  use Cwd;
Line 59  sub discussion_visible { Line 62  sub discussion_visible {
     if (not &discussion_open($status)) {      if (not &discussion_open($status)) {
  my $hidden=&Apache::lonnet::EXT('resource.0.discusshide');   my $hidden=&Apache::lonnet::EXT('resource.0.discusshide');
  if (lc($hidden) eq 'yes' or $hidden eq '' or !defined($hidden))  {   if (lc($hidden) eq 'yes' or $hidden eq '' or !defined($hidden))  {
     if (!$ENV{'request.role.adv'}) { return 0; }      if (!$env{'request.role.adv'}) { return 0; }
  }   }
     }      }
     return 1;      return 1;
 }  }
   
 sub list_discussion {  sub list_discussion {
     my ($mode,$status,$symb)=@_;      my ($mode,$status,$ressymb,$imsextras)=@_;
     my $outputtarget=$ENV{'form.grade_target'};      my $outputtarget=$env{'form.grade_target'};
     if (defined($ENV{'form.export'})) {      if (defined($env{'form.export'})) {
  if($ENV{'form.export'}) {   if($env{'form.export'}) {
             $outputtarget = 'export';              $outputtarget = 'export';
         }          }
     }          }
       if (defined($imsextras)) {
           if ($$imsextras{'caller'} eq 'imsexport') {
               $outputtarget = 'export';
           }
       }
     if (not &discussion_visible($status)) { return ''; }      if (not &discussion_visible($status)) { return ''; }
     my @bgcols = ("#cccccc","#eeeeee");      my @bgcols = ("#cccccc","#eeeeee");
     my $discussiononly=0;      my $discussiononly=0;
     if ($mode eq 'board') { $discussiononly=1; }      if ($mode eq 'board') { $discussiononly=1; }
     unless ($ENV{'request.course.id'}) { return ''; }      unless ($env{'request.course.id'}) { return ''; }
     my $crs='/'.$ENV{'request.course.id'};      my $crs='/'.$env{'request.course.id'};
     my $cid=$ENV{'request.course.id'};      my $cid=$env{'request.course.id'};
     if ($ENV{'request.course.sec'}) {      if ($env{'request.course.sec'}) {
  $crs.='_'.$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 %usernamesort = ();
     my %namesort =();      my %namesort =();
     my %subjectsort = ();      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  # Get discussion display settings for this discussion
     my $lastkey = $ressymb.'_lastread';      my $lastkey = $ressymb.'_lastread';
Line 108  sub list_discussion { Line 112  sub list_discussion {
     my $userpickkey = $ressymb.'_userpick';      my $userpickkey = $ressymb.'_userpick';
     my $toggkey = $ressymb.'_readtoggle';      my $toggkey = $ressymb.'_readtoggle';
     my $readkey = $ressymb.'_read';      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 %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 %discinfo = ();
     my $showonlyunread = 0;      my $showonlyunread = 0;
     my $showunmark = 0;       my $showunmark = 0; 
Line 122  sub list_discussion { Line 126  sub list_discussion {
   
 # Retain identification of "NEW" posts identified in last display, if continuing 'previous' browsing of posts.  # 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']);      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous','sortposts','rolefilter','statusfilter','sectionpick','totposters']);
     my $sortposts = $ENV{'form.sortposts'};      my $sortposts = $env{'form.sortposts'};
     my $rolefilter = $ENV{'form.rolefilter'};      my $statusfilter = $env{'form.statusfilter'};
     my $statusfilter = $ENV{'form.statusfilter'};      my @sectionpick = ();
     my $sectionpick = $ENV{'form.sectionpick'};      if ($env{'form.sectionpick'} =~ /,/) {
     my $totposters = $ENV{'form.totposters'};          @sectionpick = split/,/,$env{'form.sectionpick'};
     $previous = $ENV{'form.previous'};      } 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) {      if ($previous > 0) {
         $prevread = $previous;          $prevread = $previous;
     } elsif (defined($dischash{$lastkey})) {      } elsif (defined($dischash{$lastkey})) {
Line 139  sub list_discussion { Line 153  sub list_discussion {
 # Get information about students and non-students in course for filtering display of posts  # Get information about students and non-students in course for filtering display of posts
     my %roleshash = ();      my %roleshash = ();
     my %roleinfo = ();      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'});          %roleshash = &Apache::lonnet::dump('nohist_userroles',$env{'course.'.$env{'request.course.id'}.'.domain'},$env{'course.'.$env{'request.course.id'}.'.num'});
         foreach (keys %roleshash) {          foreach (keys %roleshash) {
             my ($role,$uname,$udom,$sec) = split/:/,$_;              my ($role,$uname,$udom,$sec) = split/:/,$_;
               if ($role =~ /^cr/) {
                   $role = 'cr';
               }
             my ($end,$start) = split/:/,$roleshash{$_};              my ($end,$start) = split/:/,$roleshash{$_};
             my $now = time;              my $now = time;
             my $status = 'Active';              my $status = 'Active';
             if (($now < $start) || ($end > 0 && $now > $end)) {              if (($now < $start) || ($end > 0 && $now > $end)) {
                 $status = 'Expired';                  $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(          my ($classlist) = &Apache::loncoursedata::get_classlist(
                               $ENV{'request.course.id'},                                $env{'request.course.id'},
                               $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                                $env{'course.'.$env{'request.course.id'}.'.domain'},
                               $ENV{'course.'.$ENV{'request.course.id'}.'.num'});                                $env{'course.'.$env{'request.course.id'}.'.num'});
         my $sec_index = &Apache::loncoursedata::CL_SECTION();          my $sec_index = &Apache::loncoursedata::CL_SECTION();
         my $status_index = &Apache::loncoursedata::CL_STATUS();          my $status_index = &Apache::loncoursedata::CL_STATUS();
         while (my ($student,$data) = each %$classlist) {          while (my ($student,$data) = each %$classlist) {
Line 165  sub list_discussion { Line 184  sub list_discussion {
     }      }
   
 # Get discussion display default settings for user  # Get discussion display default settings for user
     if ($ENV{'environment.discdisplay'} eq 'unread') {      if ($env{'environment.discdisplay'} eq 'unread') {
         $showonlyunread = 1;          $showonlyunread = 1;
     }      }
     if ($ENV{'environment.discmarkread'} eq 'ondisp') {      if ($env{'environment.discmarkread'} eq 'ondisp') {
         $markondisp = 1;          $markondisp = 1;
     }      }
   
Line 202  sub list_discussion { Line 221  sub list_discussion {
     $visit ++;      $visit ++;
   
     my $seeid=&Apache::lonnet::allowed('rin',$crs);      my $seeid=&Apache::lonnet::allowed('rin',$crs);
     my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)  
  && ($symb=~/\.(problem|exam|quiz|assess|survey|form)$/));  
     my @discussionitems=();      my @discussionitems=();
     my %shown = ();      my %shown = ();
     my @posteridentity=();      my @posteridentity=();
Line 220  sub list_discussion { Line 237  sub list_discussion {
     my $maxdepth=0;      my $maxdepth=0;
   
     my $target='';      my $target='';
     unless ($ENV{'browser.interface'} eq 'textual' ||      unless ($env{'browser.interface'} eq 'textual' ||
     $ENV{'environment.remote'} eq 'off' ) {      $env{'environment.remote'} eq 'off' ) {
  $target='target="LONcom"';   $target='target="LONcom"';
     }      }
   
     my $now = time;      my $now = time;
     $discinfo{$visitkey} = $visit;      $discinfo{$visitkey} = $visit;
   
     &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});      &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 $discussion='';
     my $manifestfile;      my $manifestfile;
Line 240  sub list_discussion { Line 257  sub list_discussion {
   
     my $function = &Apache::loncommon::get_users_function();      my $function = &Apache::loncommon::get_users_function();
     my $color = &Apache::loncommon::designparm($function.'.tabbg',      my $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                     $ENV{'user.domain'});                                                      $env{'user.domain'});
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'cuse' => 'Current discussion settings',          'cuse' => 'Current discussion settings',
         'allposts' => 'All posts',          'allposts' => 'All posts',
Line 306  sub list_discussion { Line 323  sub list_discussion {
     if ($visible) {      if ($visible) {
 # Print the discusssion  # Print the discusssion
         if ($outputtarget eq 'tex') {          if ($outputtarget eq 'tex') {
             $discussion.='<tex>\vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}'.              $discussion.='<tex>{\tiny \vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}'.
                          '\textbf{DISCUSSIONS}\makebox[2 cm][b]{\hrulefill}'.                           '\textbf{DISCUSSIONS}\makebox[2 cm][b]{\hrulefill}'.
                          '\vskip 0 mm\noindent\textbf{'.$lt{'cuse'}.'}:\vskip 0 mm'.                           '\vskip 0 mm\noindent\textbf{'.$lt{'cuse'}.'}:\vskip 0 mm'.
                          '\noindent\textbf{'.$lt{'disa'}.'}: \textit{'.$currdisp.'}\vskip 0 mm'.                           '\noindent\textbf{'.$lt{'disa'}.'}: \textit{'.$currdisp.'}\vskip 0 mm'.
                          '\noindent\textbf{'.$lt{'npce'}.'}: \textit{'.$currmark.'}</tex>';                           '\noindent\textbf{'.$lt{'npce'}.'}: \textit{'.$currmark.'}}</tex>';
         } elsif ($outputtarget eq 'export') {          } elsif ($outputtarget eq 'export') {
 # Create temporary directory if this is an export  # Create temporary directory if this is an export
             my $now = time;              my $now = time;
             $tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports';              if ((defined($imsextras)) && ($$imsextras{'caller'} eq 'imsexport')) {
             if (!-e $tempexport) {                  $tempexport = $$imsextras{'tempexport'};
                 mkdir($tempexport,0700);                  if (!-e $tempexport) {
             }                      mkdir($tempexport,0700);
             $tempexport .= '/'.$now;                  }
             if (!-e $tempexport) {                  $tempexport .= '/'.$$imsextras{'count'};
                 mkdir($tempexport,0700);                  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) {              if (!-e $tempexport) {
                 mkdir($tempexport,0700);                  mkdir($tempexport,0700);
             }              }
Line 359  imscp_v1p1.xsd http://www.imsglobal.org/ Line 387  imscp_v1p1.xsd http://www.imsglobal.org/
    }     }
 </script>  </script>
             |;              |;
     $discussion.='<form name="readchoices" method="post" action="/adm/feedback?chgreads='.$symb.'"><table bgcolor="#AAAAAA" cellpadding="2" cellspacing="2" border="0">';      $discussion.='<form name="readchoices" method="post" action="/adm/feedback?chgreads='.$ressymb.'" ><table bgcolor="#AAAAAA" cellpadding="2" cellspacing="2" border="0">';
     $discussion .='<tr><td bgcolor="#DDDDBB" colspan="'.$colspan.'">'.      $discussion .='<tr><td bgcolor="#DDDDBB" colspan="'.$colspan.'">'.
  '<table border="0" width="100%" bgcolor="#DDDDBB"><tr>';   '<table border="0" width="100%" bgcolor="#DDDDBB"><tr>';
     if ($visible>2) {      if ($visible>2) {
  $discussion.='<td align="left">'.   $discussion.='<td align="left">'.
     '<a href="/adm/feedback?threadedon='.$ressymb;      '<a href="/adm/feedback?cmd=threadedon&amp;symb='.$ressymb;
  if ($newpostsflag) {   if ($newpostsflag) {
     $discussion .= '&previous='.$prevread;      $discussion .= '&previous='.$prevread;
  }   }
  $discussion .='">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.   $discussion .='">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.
     '<a href="/adm/feedback?threadedoff='.$ressymb;      '<a href="/adm/feedback?cmd=threadedoff&amp;symb='.$ressymb;
  if ($newpostsflag) {   if ($newpostsflag) {
     $discussion .= '&previous='.$prevread;      $discussion .= '&previous='.$prevread;
  }   }
  $discussion .='">'.&mt('Chronological View').'</a>&nbsp;&nbsp;   $discussion .='">'.&mt('Chronological View').'</a>&nbsp;&nbsp;
                               <a href= "/adm/feedback?sortfilter='.$ressymb;                                <a href= "/adm/feedback?cmd=sortfilter&amp;symb='.$ressymb;
                 if ($newpostsflag) {                  if ($newpostsflag) {
                     $discussion .= '&previous='.$prevread;                      $discussion .= '&previous='.$prevread;
                 }                  }
Line 389  imscp_v1p1.xsd http://www.imsglobal.org/ Line 417  imscp_v1p1.xsd http://www.imsglobal.org/
             $discussion .= '">'.&mt('Export').'?</a>&nbsp;&nbsp;</td>';              $discussion .= '">'.&mt('Export').'?</a>&nbsp;&nbsp;</td>';
     if ($newpostsflag) {      if ($newpostsflag) {
  if (!$markondisp) {   if (!$markondisp) {
     $discussion .='<td align="right"><a href="/adm/feedback?markread='.$ressymb.'">'.&mt('Mark NEW posts no longer new').'</a>&nbsp;&nbsp;';      $discussion .='<td align="right"><a href="/adm/feedback?markread=1&amp;symb='.$ressymb.'">'.&mt('Mark NEW posts no longer new').'</a>&nbsp;&nbsp;';
  } else {   } else {
     $discussion .= '<td>&nbsp;</td>';      $discussion .= '<td>&nbsp;</td>';
  }   }
Line 402  imscp_v1p1.xsd http://www.imsglobal.org/ Line 430  imscp_v1p1.xsd http://www.imsglobal.org/
             if ($numhidden > 0) {              if ($numhidden > 0) {
                 my $colspan = $maxdepth+1;                  my $colspan = $maxdepth+1;
                 $discussion.="\n".'<tr><td bgcolor="#CCCCCC" colspan="'.$colspan.'">'.                  $discussion.="\n".'<tr><td bgcolor="#CCCCCC" colspan="'.$colspan.'">'.
                          '<a href="/adm/feedback?allposts='.$ressymb;                           '<a href="/adm/feedback?allposts=1&amp;symb='.$ressymb;
                 if ($newpostsflag) {                  if ($newpostsflag) {
                     $discussion .= '&previous='.$prevread;                      $discussion .= '&previous='.$prevread;
                 }                  }
Line 440  imscp_v1p1.xsd http://www.imsglobal.org/ Line 468  imscp_v1p1.xsd http://www.imsglobal.org/
                  }                   }
             }              }
         } else {          } else {
             $sortposts = 'ascdate';  
             @showposts =  (sort { $a <=> $b } keys %alldiscussion);              @showposts =  (sort { $a <=> $b } keys %alldiscussion);
         }          }
         my $currdepth = 0;          my $currdepth = 0;
         my $firstidx = $alldiscussion{$showposts[0]};          my $firstidx = $alldiscussion{$showposts[0]};
         foreach (@showposts) {          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{$_} = $_;                  $alldiscussion{$_} = $_;
             }              }
             unless ( ($notshown{$alldiscussion{$_}} eq '1') || ($shown{$alldiscussion{$_}} == 0) ) {              unless ( ($notshown{$alldiscussion{$_}} eq '1') || ($shown{$alldiscussion{$_}} == 0) ) {
Line 486  imscp_v1p1.xsd http://www.imsglobal.org/ Line 513  imscp_v1p1.xsd http://www.imsglobal.org/
         $imsitems{$alldiscussion{$_}}{'isvisible'}.'" identifieref="RES-'.$ressymb.'-'.$alldiscussion{$_}.'">'.          $imsitems{$alldiscussion{$_}}{'isvisible'}.'" identifieref="RES-'.$ressymb.'-'.$alldiscussion{$_}.'">'.
         '<title>'.$imsitems{$alldiscussion{$_}}{'title'}.'</title>';          '<title>'.$imsitems{$alldiscussion{$_}}{'title'}.'</title>';
                         $imsresources .= "\n".                          $imsresources .= "\n".
     '<resource identifier="RES-'.$ressymb.'-'.$alldiscussion{$_}.'" type="webcontent" href="'.$postfilename.'">'.      '<resource identifier="RES-'.$ressymb.'-'.$alldiscussion{$_}.'" type="webcontent" href="'.$postfilename.'">'."\n".
       '<file href="'.$alldiscussion{$_}.'.html">'."\n".        '<file href="'.$postfilename.'">'."\n".
       $imsfiles{$alldiscussion{$_}}{$imsitems{$alldiscussion{$_}}{'currversion'}}."\n".        $imsfiles{$alldiscussion{$_}}{$imsitems{$alldiscussion{$_}}{'currversion'}}."\n".
     '</resource>';      '</resource>';
                     }                      }
Line 544  END Line 571  END
             $discussion .= <<END;              $discussion .= <<END;
                    </font></td>                     </font></td>
                    <td>&nbsp;</td>                     <td>&nbsp;</td>
                    <td>                     <td align="left">
                     <font size="-1"><b><a href="$chglink">$lt{'chgt'}</a>?</font></b>                      <font size="-1"><b><a href="$chglink">$lt{'chgt'}</a>?</font></b>
                    </td>                     </td>
                   </tr>                    </tr>
                  </table>                   </table>
                 </td>                  </td>
 END  END
               if ($sortposts) {
                   my %sort_types = ();
                   my %role_types = ();
                   my %status_types = ();
                   &sort_filter_names(\%sort_types,\%role_types,\%status_types);
   
                   $discussion .= '<td><font size="-1"><b>'.&mt('Sorted by').'</b>: '.$sort_types{$sortposts}.'<br />';
                   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 = '<i>'.&mt('sections').'</i>-&nbsp;'.$env{'form.sectionpick'};
                           $filterchoice .= '&nbsp;&nbsp;&nbsp; ';
                       }
                       if (@rolefilter > 0) {
                           $filterchoice .= '<i>'.&mt('roles').'</i>-';
                           foreach (@rolefilter) {
                               $filterchoice .= '&nbsp;'.$role_types{$_}.',';
                           }
                           $filterchoice =~ s/,$//;
                           $filterchoice .= '<br />&nbsp;&nbsp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp&nbsp;';
                       }
                       if ($statusfilter) {
                           $filterchoice .= '<i>'.&mt('status').'</i>-&nbsp;'.$status_types{$statusfilter};
                       }
                       if ($filterchoice) {
                           $discussion .= '<b>'.&mt('Filters').'</b>:&nbsp;'.$filterchoice;
                       }
                       $discussion .= '</font></td>';
                   }
               }
             if ($dischash{$toggkey}) {              if ($dischash{$toggkey}) {
                 my $storebutton = &mt('Store read/unread changes');                  my $storebutton = &mt('Store read/unread changes');
                 $discussion.='<td align="right">'.                  $discussion.='<td align="right">'.
Line 583  END Line 651  END
 </manifest>  </manifest>
                 |;                  |;
                 close($manifestfile);                  close($manifestfile);
                   if ((defined($imsextras)) && ($$imsextras{'caller'} eq 'imsexport')) {
                       $discussion = $copyresult;
                   } else {
   
 #Create zip file in prtspool  #Create zip file in prtspool
   
                 my $imszipfile = '/prtspool/'.                      my $imszipfile = '/prtspool/'.
                 $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.                      $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
                      time.'_'.rand(1000000000).'.zip';                           time.'_'.rand(1000000000).'.zip';
     # zip can cause an sh launch which can pass along all of %ENV                      my $cwd = &getcwd(); 
     # which can be too large for /bin/sh to handle                      my $imszip = '/home/httpd/'.$imszipfile;
                 my %oldENV=%ENV;                      chdir $tempexport;
                 undef(%ENV);                      open(OUTPUT, "zip -r $imszip *  2> /dev/null |");
                 my $cwd = &getcwd();                       close(OUTPUT);
                 my $imszip = '/home/httpd/'.$imszipfile;                      chdir $cwd;
                 chdir $tempexport;                      $discussion .= 'Download the zip file from <a href="'.$imszipfile.'">Discussion Posting Archive</a><br />';
                 open(OUTPUT, "zip -r $imszip *  2> /dev/null |");                      if ($copyresult) {
                 close(OUTPUT);                          $discussion .= 'The following errors occurred during export - <br />'.$copyresult;
                 chdir $cwd;                      }
                 %ENV=%oldENV;  
                 undef(%oldENV);  
                 $discussion .= 'Download the zip file from <a href="'.$imszipfile.'">Discussion Posting Archive</a><br />';  
                 if ($copyresult) {  
                     $discussion .= 'The following errors occurred during export - <br />'.$copyresult;  
                 }                  }
             } else {              } else {
                 $discussion .= '<br />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.<br />';                  $discussion .= '<br />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.<br />';
Line 619  END Line 685  END
         my @currdelold = ();          my @currdelold = ();
         my $comment = '';          my $comment = '';
         my $subject = '';          my $subject = '';
         if ($ENV{'form.origpage'}) {          if ($env{'form.origpage'}) {
             &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['addnewattach','deloldattach','delnewattach','timestamp','idx','subject','comment']);              &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['addnewattach','deloldattach','delnewattach','timestamp','idx','subject','comment']);
             $subject = &Apache::lonnet::unescape($ENV{'form.subject'});              $subject = &Apache::lonnet::unescape($env{'form.subject'});
             $comment = &Apache::lonnet::unescape($ENV{'form.comment'});              $comment = &Apache::lonnet::unescape($env{'form.comment'});
             my @keepold = ();              my @keepold = ();
             &process_attachments(\@currnewattach,\@currdelold,\@keepold);              &process_attachments(\@currnewattach,\@currdelold,\@keepold);
             if (@currnewattach > 0) {              if (@currnewattach > 0) {
Line 643  to course faculty</font><br /> Line 709  to course faculty</font><br />
 <b>Title:</b>&nbsp;<input type="text" name="subject" value="$subject" size="30" /><br /><br />  <b>Title:</b>&nbsp;<input type="text" name="subject" value="$subject" size="30" /><br /><br />
 <textarea name="comment" cols="80" rows="14" wrap="hard">$comment</textarea>  <textarea name="comment" cols="80" rows="14" wrap="hard">$comment</textarea>
 ENDDISCUSS  ENDDISCUSS
         if ($ENV{'form.origpage'}) {              if ($env{'form.origpage'}) {
             $discussion.='<input type="hidden" name="origpage" value="'.$ENV{'form.origpage'}.'" />'."\n";                  $discussion.='<input type="hidden" name="origpage" value="'.$env{'form.origpage'}.'" />'."\n";
             foreach (@currnewattach) {                  foreach (@currnewattach) {
                 $discussion.='<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n";                      $discussion.='<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n";
             }                  }
         }              }
         $discussion.="</form>\n";              $discussion.="</form>\n";
         if ($outputtarget ne 'tex') {              if ($outputtarget ne 'tex') {
             $discussion.=&generate_attachments_button('',$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,'',$mode);                  $discussion.=&generate_attachments_button('',$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,'',$mode);
             if (@currnewattach > 0) {                  if (@currnewattach > 0) {
                 $newattachmsg .= '<b>New attachments</b><br />';                      $newattachmsg .= '<b>New attachments</b><br />';
                 if (@currnewattach > 1) {                      if (@currnewattach > 1) {
                     $newattachmsg .= '<ol>';                          $newattachmsg .= '<ol>';
                     foreach my $item (@currnewattach) {                          foreach my $item (@currnewattach) {
                         $item =~ m#.*/([^/]+)$#;                              $item =~ m#.*/([^/]+)$#;
                         $newattachmsg .= '<li><a href="'.$item.'">'.$1.'</a></li>'."\n";                              $newattachmsg .= '<li><a href="'.$item.'">'.$1.'</a></li>'."\n";
                           }
                           $newattachmsg .= '</ol>'."\n";
                       } else {
                           $currnewattach[0] =~ m#.*/([^/]+)$#;
                           $newattachmsg .= '<a href="'.$currnewattach[0].'">'.$1.'</a><br />'."\n";
                     }                      }
                     $newattachmsg .= '</ol>'."\n";  
                 } else {  
                     $currnewattach[0] =~ m#.*/([^/]+)$#;  
                     $newattachmsg .= '<a href="'.$currnewattach[0].'">'.$1.'</a><br />'."\n";  
                 }                  }
             }                  $discussion.=$newattachmsg;
             $discussion.=$newattachmsg;          $discussion.=&generate_preview_button();
     $discussion.=&generate_preview_button();      }
  }  
  }   }
         } else {      } else {
  if (&discussion_open($status) &&          if (&discussion_open($status) &&
     &Apache::lonnet::allowed('pch',              &Apache::lonnet::allowed('pch',
    $ENV{'request.course.id'}.             $env{'request.course.id'}.
  ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {          ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
     if ($outputtarget ne 'tex') {      if ($outputtarget ne 'tex') {
  $discussion.='<table bgcolor="#BBBBBB"><tr><td><a href="/adm/feedback?replydisc='.   $discussion.='<table bgcolor="#BBBBBB"><tr><td><a href="/adm/feedback?replydisc='.
     $symb.':::" '.$target.'>'.      $ressymb.':::" '.$target.'>'.
     '<img src="/adm/lonMisc/chat.gif" border="0" />'.      '<img src="'.&Apache::loncommon::lonhttpdurl('/adm/lonMisc/chat.gif').'" border="0" />'.
     &mt('Post Discussion').'</a></td></tr></table>';      &mt('Post Discussion').'</a></td></tr></table>';
     }      }
  }   }
Line 688  ENDDISCUSS Line 754  ENDDISCUSS
   
 sub build_posting_display {  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 ($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 @original=();
     my @index=();      my @index=();
       my $symb=&Apache::lonenc::check_decrypt($ressymb);
     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'}.'.domain'},
   $ENV{'course.'.$ENV{'request.course.id'}.'.num'});    $env{'course.'.$env{'request.course.id'}.'.num'});
   
     if ($contrib{'version'}) {      if ($contrib{'version'}) {
         my $oldest = $contrib{'1:timestamp'};          my $oldest = $contrib{'1:timestamp'};
         if ($prevread eq '0') {          if ($prevread eq '0') {
             $prevread = $oldest-1;              $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++) {   for (my $id=1;$id<=$contrib{'version'};$id++) {
     my $idx=$id;      my $idx=$id;
             my $posttime = $contrib{$idx.':timestamp'};              my $posttime = $contrib{$idx.':timestamp'};
Line 713  sub build_posting_display { Line 783  sub build_posting_display {
     my $origindex='0.';      my $origindex='0.';
             my $numoldver=0;              my $numoldver=0;
     if ($contrib{$idx.':replyto'}) {      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  # this is a follow-up message
     $original[$idx]=$original[$contrib{$idx.':replyto'}];      $original[$idx]=$original[$contrib{$idx.':replyto'}];
     $$depth[$idx]=$$depth[$contrib{$idx.':replyto'}]+1;      $$depth[$idx]=$$depth[$contrib{$idx.':replyto'}]+1;
Line 821  sub build_posting_display { Line 891  sub build_posting_display {
                             } else {                              } else {
                                 @{$$namesort{$lastname}{$firstname}} = ("$idx");                                  @{$$namesort{$lastname}{$firstname}} = ("$idx");
                             }                              }
                             if ($ENV{'course.'.$ENV{'request.course.id'}.'.allow_discussion_post_editing'} =~ m/yes/i) {                              if ($env{'course.'.$env{'request.course.id'}.'.allow_discussion_post_editing'} =~ m/yes/i) {
                                 if (($ENV{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($ENV{'user.name'} eq $contrib{$idx.':sendername'})) {                                  if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) {
                                     $sender.=' <a href="/adm/feedback?editdisc='.                                      $sender.=' <a href="/adm/feedback?editdisc='.
                                          $ressymb.':::'.$idx;                                           $ressymb.':::'.$idx;
                                     if ($newpostsflag) {                                      if ($newpostsflag) {
Line 885  sub build_posting_display { Line 955  sub build_posting_display {
         }          }
         if (&discussion_open($status) &&          if (&discussion_open($status) &&
         &Apache::lonnet::allowed('pch',          &Apache::lonnet::allowed('pch',
  $ENV{'request.course.id'}.   $env{'request.course.id'}.
  ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {   ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
     $sender.=' <a href="/adm/feedback?replydisc='.      $sender.=' <a href="/adm/feedback?replydisc='.
             $ressymb.':::'.$idx;              $ressymb.':::'.$idx;
                             if ($newpostsflag) {                              if ($newpostsflag) {
Line 899  sub build_posting_display { Line 969  sub build_posting_display {
                             $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$ressymb);                              $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$ressymb);
         }          }
                         if ($$dischash{$readkey}=~/\.$idx\./) {                           if ($$dischash{$readkey}=~/\.$idx\./) { 
                             $ctlink = '<b>'.&mt('Mark unread').'?</b>&nbsp;<input type="checkbox" name="postunread_'.$idx.'" />';                              $ctlink = '<label><b>'.&mt('Mark unread').'?</b>&nbsp;<input type="checkbox" name="postunread_'.$idx.'" /></label>';
                         } else {                          } else {
                             $ctlink = '<b>'.&mt('Mark read').'?</b>&nbsp;<input type="checkbox" name="postread_'.$idx.'" />';                              $ctlink = '<label><b>'.&mt('Mark read').'?</b>&nbsp;<input type="checkbox" name="postread_'.$idx.'" /></label>';
                         }                          }
                     }                      }
 #figure out at what position this needs to print  #figure out at what position this needs to print
                 }                  }
                 if ($outputtarget eq 'export' || $message) {                  if ($outputtarget eq 'export' || $message) {
     my $thisindex=$idx;      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);   $thisindex=$origindex.substr('00'.$$replies[$$depth[$idx]],-2,2);
     }      }
     $$alldiscussion{$thisindex}=$idx;      $$alldiscussion{$thisindex}=$idx;
Line 949  sub build_posting_display { Line 1019  sub build_posting_display {
                             my $uname = $contrib{$idx.':sendername'};                              my $uname = $contrib{$idx.':sendername'};
                             my $udom = $contrib{$idx.':senderdomain'};                              my $udom = $contrib{$idx.':senderdomain'};
                             my $poster = $uname.':'.$udom;                              my $poster = $uname.':'.$udom;
                             my $rolematch = '';                              if (defined($env{'form.totposters'})) {
                             my $skiptest = 1;                                  if ($totposters == 0) {
                             if ($totposters > 0) {                                      $$shown{$idx} = 0;
                                 if (grep/^$poster$/,@{$posters}) {                                  } elsif ($totposters > 0) {
                                     $$shown{$idx} = 1;                                      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;  
                                     }                                      }
                                 }                                  }
                               } elsif ($sortposts) {
                                 if ($skiptest) {                                  if ($skiptest) {
                                     $$shown{$idx} = 1;                                      $$shown{$idx} = 1;
                                 } else {                                  } else {
                                     foreach my $role (@{$$roleinfo{$poster}}) {                                      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;                                              $$shown{$idx} = 1;
                                             last;                                              last;
                                         }                                          }
                                     }                                      }
                                 }                                  }
                               } else {
                                   $$shown{$idx} = 1;
                             }                              }
                         }                          }
                         unless ($$notshown{$idx} == 1) {                          unless ($$notshown{$idx} == 1) {
Line 1039  sub build_posting_display { Line 1095  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 {  sub get_post_contents {
     my ($contrib,$idx,$seeid,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$numver) = @_;      my ($contrib,$idx,$seeid,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$numver) = @_;
     my $discussion = '';      my $discussion = '';
Line 1177  sub replicate_attachments { Line 1287  sub replicate_attachments {
   
 sub mail_screen {  sub mail_screen {
   my ($r,$feedurl,$options) = @_;    my ($r,$feedurl,$options) = @_;
   if (exists($ENV{'form.origpage'})) {    if (exists($env{'form.origpage'})) {
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','currnewattach','addnewattach','deloldattach','delnewattach','timestamp','idx','anondiscuss','discuss']);        &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','currnewattach','addnewattach','deloldattach','delnewattach','timestamp','idx','anondiscuss','discuss']);
   }    }
   my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion',    my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion',
Line 1211  sub mail_screen { Line 1321  sub mail_screen {
    }     }
 END  END
   my $anonscript;    my $anonscript;
   if (exists($ENV{'form.origpage'})) {    if (exists($env{'form.origpage'})) {
       $anonscript = (<<END);        $anonscript = (<<END);
   function setposttype() {    function setposttype() {
       var anondisc = $ENV{'form.anondiscuss'};        var anondisc = $env{'form.anondiscuss'};
       var disc = $ENV{'form.discuss'};        var disc = $env{'form.discuss'};
       if (anondisc == 1) {        if (anondisc == 1) {
           document.mailform.anondiscuss.checked = true            document.mailform.anondiscuss.checked = true
       }        }
Line 1232  END Line 1342  END
   }    }
 END  END
   }    }
   if (($ENV{'form.replydisc'}) || ($ENV{'form.editdisc'})) {    if (($env{'form.replydisc'}) || ($env{'form.editdisc'})) {
       if ($ENV{'form.replydisc'}) {        if ($env{'form.replydisc'}) {
           ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'});            ($symb,$idx)=split(/\:\:\:/,$env{'form.replydisc'});
       } else {        } else {
           ($symb,$idx)=split(/\:\:\:/,$ENV{'form.editdisc'});            ($symb,$idx)=split(/\:\:\:/,$env{'form.editdisc'});
       }        }
       my %contrib=&Apache::lonnet::restore($symb,$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'}.'.domain'},
    $ENV{'course.'.$ENV{'request.course.id'}.'.num'});     $env{'course.'.$env{'request.course.id'}.'.num'});
       unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) {        unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) {
           if ($contrib{$idx.':history'}) {            if ($contrib{$idx.':history'}) {
               if ($contrib{$idx.':history'} =~ /:/) {                if ($contrib{$idx.':history'} =~ /:/) {
Line 1250  END Line 1360  END
                   $numoldver = 1;                    $numoldver = 1;
               }                }
           }            }
           if ($ENV{'form.replydisc'}) {            if ($env{'form.replydisc'}) {
               if ($contrib{$idx.':history'}) {                if ($contrib{$idx.':history'}) {
                   if ($contrib{$idx.':history'} =~ /:/) {                    if ($contrib{$idx.':history'} =~ /:/) {
                       my @oldversions = split/:/,$contrib{$idx.':history'};                        my @oldversions = split/:/,$contrib{$idx.':history'};
Line 1286  END Line 1396  END
               if (defined($contrib{$idx.':replyto'})) {                if (defined($contrib{$idx.':replyto'})) {
                   $parentmsg = $contrib{$idx.':replyto'};                    $parentmsg = $contrib{$idx.':replyto'};
               }                }
               unless (exists($ENV{'form.origpage'})) {                unless (exists($env{'form.origpage'})) {
                   my $anonflag = 0;                    my $anonflag = 0;
                   if ($contrib{$idx.':anonymous'}) {                    if ($contrib{$idx.':anonymous'}) {
                       $anonflag = 1;                        $anonflag = 1;
Line 1308  END Line 1418  END
               }                }
           }            }
       }        }
       if ($ENV{'form.previous'}) {        if ($env{'form.previous'}) {
           $prevtag = '<input type="hidden" name="previous" value="'.$ENV{'form.previous'}.'" />';            $prevtag = '<input type="hidden" name="previous" value="'.$env{'form.previous'}.'" />';
       }        }
   }    }
   
   if ($ENV{'form.origpage'}) {    if ($env{'form.origpage'}) {
       $subject = &Apache::lonnet::unescape($ENV{'form.subject'});        $subject = &Apache::lonnet::unescape($env{'form.subject'});
       $comment = &Apache::lonnet::unescape($ENV{'form.comment'});        $comment = &Apache::lonnet::unescape($env{'form.comment'});
       &process_attachments(\@currnewattach,\@currdelold,\@keepold);        &process_attachments(\@currnewattach,\@currdelold,\@keepold);
   }    }
   my $latexHelp=&Apache::loncommon::helpLatexCheatsheet();    my $latexHelp=&Apache::loncommon::helpLatexCheatsheet();
   my $htmlheader=&Apache::lonhtmlcommon::htmlareaheaders();    my $htmlheader=&Apache::lonhtmlcommon::htmlareaheaders();
   my $send=&mt('Send');    my $send=&mt('Send');
     my $html=&Apache::lonxml::xmlbegin();
   $r->print(<<END);    $r->print(<<END);
 <html>  $html
 <head>  <head>
 <title>The LearningOnline Network with CAPA</title>  <title>The LearningOnline Network with CAPA</title>
 <meta http-equiv="pragma" content="no-cache"></meta>  <meta http-equiv="pragma" content="no-cache"></meta>
Line 1383  enctype="multipart/form-data"> Line 1494  enctype="multipart/form-data">
 $prevtag  $prevtag
 <input type="hidden" name="postdata" value="$feedurl" />  <input type="hidden" name="postdata" value="$feedurl" />
 END  END
   if ($ENV{'form.replydisc'}) {    if ($env{'form.replydisc'}) {
       $r->print(<<END);        $r->print(<<END);
 <input type="hidden" name="replydisc" value="$ENV{'form.replydisc'}" />  <input type="hidden" name="replydisc" value="$env{'form.replydisc'}" />
 END  END
   } elsif ($ENV{'form.editdisc'}) {    } elsif ($env{'form.editdisc'}) {
      $r->print(<<END);       $r->print(<<END);
 <input type="hidden" name="editdisc" value ="$ENV{'form.editdisc'}" />  <input type="hidden" name="editdisc" value ="$env{'form.editdisc'}" />
 <input type="hidden" name="parentmsg" value ="$parentmsg" />  <input type="hidden" name="parentmsg" value ="$parentmsg" />
 END  END
   }    }
Line 1406  Title: <input type="text" name="subject" Line 1517  Title: <input type="text" name="subject"
 </textarea></p>  </textarea></p>
 <p>  <p>
 END  END
     if ( ($ENV{'form.editdisc'}) || ($ENV{'form.replydisc'}) ) {      if ( ($env{'form.editdisc'}) || ($env{'form.replydisc'}) ) {
         if ($ENV{'form.origpage'}) {          if ($env{'form.origpage'}) {
             foreach (@currnewattach) {              foreach (@currnewattach) {
                 $r->print('<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n");                  $r->print('<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n");
             }              }
Line 1415  END Line 1526  END
                 $r->print('<input type="hidden" name="deloldattach" value="'.$_.'" />'."\n");                  $r->print('<input type="hidden" name="deloldattach" value="'.$_.'" />'."\n");
             }              }
         }          }
         if ($ENV{'form.editdisc'}) {          if ($env{'form.editdisc'}) {
             if ($attachmenturls) {              if ($attachmenturls) {
                 &extract_attachments($attachmenturls,$idx,$numoldver,\$attachmsg,\%attachments,\%currattach,\@currdelold);                  &extract_attachments($attachmenturls,$idx,$numoldver,\$attachmsg,\%attachments,\%currattach,\@currdelold);
                 $attachnum = scalar(keys %currattach);                  $attachnum = scalar(keys %currattach);
Line 1437  END Line 1548  END
 </p>  </p>
 </form>  </form>
 END  END
     if ($ENV{'form.editdisc'} || $ENV{'form.replydisc'}) {      if ($env{'form.editdisc'} || $env{'form.replydisc'}) {
         my $now = time;          my $now = time;
         my $ressymb = $symb;          my $ressymb = $symb;
         my $postidx = '';          my $postidx = '';
         if ($ENV{'form.editdisc'}) {          if ($env{'form.editdisc'}) {
             $postidx = $idx;              $postidx = $idx;
         }          }
         if (@currnewattach > 0) {          if (@currnewattach > 0) {
Line 1478  END Line 1589  END
   
 sub print_display_options {  sub print_display_options {
     my ($r,$symb,$previous,$dispchgA,$dispchgB,$markchg,$toggchg,$feedurl) = @_;      my ($r,$symb,$previous,$dispchgA,$dispchgB,$markchg,$toggchg,$feedurl) = @_;
  # backward compatibility (bulletin boards used to be 'wrapped')      &Apache::loncommon::content_type($r,'text/html');
     if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {      $r->send_http_header;
         $feedurl=~s|^/adm/wrapper||;  
     }  
   
     my $function = &Apache::loncommon::get_users_function();      my $function = &Apache::loncommon::get_users_function();
     my $tabcolor = &Apache::loncommon::designparm($function.'.tabbg',      my $tabcolor = &Apache::loncommon::designparm($function.'.tabbg',
                                                     $ENV{'user.domain'});                                                      $env{'user.domain'});
     my $bodytag=&Apache::loncommon::bodytag('Discussion options',      my $bodytag=&Apache::loncommon::bodytag('Discussion options',
                                           '','');                                            '','');
   
Line 1548  sub print_display_options { Line 1657  sub print_display_options {
         $currtogg = $lt{'toggon'};          $currtogg = $lt{'toggon'};
         $disctogg = 'toggon';          $disctogg = 'toggon';
     }      }
       my $html=&Apache::lonxml::xmlbegin();
     $r->print(<<END);      $r->print(<<END);
 <html>  $html
 <head>  <head>
 <title>$lt{'dido'}</title>  <title>$lt{'dido'}</title>
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
Line 1640  $lt{'sdpf'}<br/> $lt{'prca'}  <ol><li>$l Line 1750  $lt{'sdpf'}<br/> $lt{'prca'}  <ol><li>$l
        <tr bgcolor="#dddddd">         <tr bgcolor="#dddddd">
        <td>$lt{'disa'}</td>         <td>$lt{'disa'}</td>
        <td>$lt{$discdisp}</td>         <td>$lt{$discdisp}</td>
        <td><input type="checkbox" name="discdisp" onClick="discdispChk('0')" />&nbsp;$lt{'chgt'} "$dispchangeA"         <td><label><input type="checkbox" name="discdisp" onClick="discdispChk('0')" />&nbsp;$lt{'chgt'} "$dispchangeA"</label>
            <br />             <br />
            <input type="checkbox" name="discdisp" onClick="discdispChk('1')" />&nbsp;$lt{'chgt'} "$dispchangeB"             <label><input type="checkbox" name="discdisp" onClick="discdispChk('1')" />&nbsp;$lt{'chgt'} "$dispchangeB"</label>
        </td>         </td>
       </tr><tr bgcolor="#eeeeee">        </tr><tr bgcolor="#eeeeee">
        <td>$lt{'npmr'}</td>         <td>$lt{'npmr'}</td>
        <td>$lt{$discmark}</td>         <td>$lt{$discmark}</td>
        <td><input type="checkbox" name="discmark" />$lt{'chgt'} "$markchange"</td>         <td><label><input type="checkbox" name="discmark" />$lt{'chgt'} "$markchange"</label></td>
       </tr><tr bgcolor="#dddddd">        </tr><tr bgcolor="#dddddd">
        <td>$lt{'dotm'}</td>         <td>$lt{'dotm'}</td>
        <td>$lt{$disctogg}</td>         <td>$lt{$disctogg}</td>
        <td><input type="checkbox" name="disctogg" onClick="discdispChk('2')" />$lt{'chgt'} "$toggchange"</td>         <td><label><input type="checkbox" name="disctogg" onClick="discdispChk('2')" />$lt{'chgt'} "$toggchange"</label></td>
       </tr>        </tr>
      </table>       </table>
     </td>      </td>
Line 1662  $lt{'sdpf'}<br/> $lt{'prca'}  <ol><li>$l Line 1772  $lt{'sdpf'}<br/> $lt{'prca'}  <ol><li>$l
 </table>  </table>
 <br />  <br />
 <br />  <br />
   <input type="hidden" name="symb" value="$symb" />
 <input type="hidden" name="previous" value="$previous" />  <input type="hidden" name="previous" value="$previous" />
 <input type="hidden" name="$dispchgA" value=""/>  <input type="hidden" name="$dispchgA" value=""/>
 <input type="hidden" name="$dispchgB" value=""/>  <input type="hidden" name="$dispchgB" value=""/>
Line 1679  END Line 1790  END
   
 sub print_sortfilter_options {  sub print_sortfilter_options {
     my ($r,$symb,$previous,$feedurl) = @_;      my ($r,$symb,$previous,$feedurl) = @_;
  # backward compatibility (bulletin boards used to be 'wrapped')  
     if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {      &Apache::loncommon::content_type($r,'text/html');
         $feedurl=~s|^/adm/wrapper||;      $r->send_http_header;
     }  
       &Apache::lonenc::check_encrypt(\$symb);
     my @sections = ();      my @sections = ();
     my $section_sel = '';      my $section_sel = '';
     my $numsections = 0;      my $numsections = 0;
     my $numvisible = 5;      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 = ();      my %sectioncount = ();
     while (my ($student,$data) = each %$classlist) {  
         my ($section,$status) = ($data->[$sec_index],      $numsections = &Apache::loncommon::get_sections($env{'course.'.$env{'request.course.id'}.'.domain'},$env{'course.'.$env{'request.course.id'}.'.num'},\%sectioncount);
                                  $data->[$status_index]);  
         unless ($section eq '' || $section =~ /^\s*$/) {      if ($env{'request.course.sec'} !~ /^\s*$/) {  #Restrict section choice to current section 
             if (!defined($sectioncount{$section})) {          @sections = ('all',$env{'request.course.sec'});
                 $sectioncount{$section} = 1;          $numvisible = 2;
                 $numsections ++;  
             } else {  
                 $sectioncount{$section} ++;  
             }  
         }  
     }  
                                                                                      
     if ($ENV{'request.course.sec'} !~ /^\s*$/) {  
         @sections = ($ENV{'request.course.sec'});  
         $numvisible = 1;  
     } else {      } else {
         @sections = sort {$a cmp $b} keys(%sectioncount);          @sections = sort {$a cmp $b} keys(%sectioncount);
         unshift(@sections,'all'); # Put 'all' at the front of the list          unshift(@sections,'all'); # Put 'all' at the front of the list
Line 1724  sub print_sortfilter_options { Line 1819  sub print_sortfilter_options {
                                                                                                                                                                         
     my $function = &Apache::loncommon::get_users_function();      my $function = &Apache::loncommon::get_users_function();
     my $tabcolor = &Apache::loncommon::designparm($function.'.tabbg',      my $tabcolor = &Apache::loncommon::designparm($function.'.tabbg',
                                                     $ENV{'user.domain'});                                                      $env{'user.domain'});
     my $bodytag=&Apache::loncommon::bodytag('Discussion options',      my $bodytag=&Apache::loncommon::bodytag('Discussion options',
                                           '','');                                            '','');
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
Line 1732  sub print_sortfilter_options { Line 1827  sub print_sortfilter_options {
         'diop' => 'Display Options',          'diop' => 'Display Options',
         'curr' => 'Current setting ',          'curr' => 'Current setting ',
         'actn' => 'Action',          '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',          'soor' => 'Sort order',
         'disp' => 'Specific user roles',          'spur' => 'Specific user roles',
         'actv' => 'Specific role status',          'sprs' => 'Specific role status',
         'spse' => 'Specific sections',          'spse' => 'Specific sections',
         'psub' => 'Pick specific users (by name)',          'psub' => 'Pick specific users (by name)',
         'shal' => 'Show a list of current posters'          '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);
       my $html=&Apache::lonxml::xmlbegin();
     $r->print(<<END);      $r->print(<<END);
 <html>  $html
 <head>  <head>
 <title>$lt{'diso'}</title>  <title>$lt{'diso'}</title>
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
   <script type="text/javascript">
   function verifyFilter() {
       var rolenum = 0
       for (var i=0; i<document.modifyshown.rolefilter.length; i++) {
           if (document.modifyshown.rolefilter.options[i].selected == true) {
               rolenum ++
           }
       }
       if (rolenum == 0) {
           document.modifyshown.rolefilter.options[0].selected = true
       }
   
       var secnum = 0
       for (var i=0; i<document.modifyshown.sectionpick.length; i++) {
           if (document.modifyshown.sectionpick.options[i].selected == true) {
               secnum ++
           }
       }
       if (secnum == 0) {
           document.modifyshown.sectionpick.options[0].selected = true
       }
       document.modifyshown.submit();
   }
   </script>
 </head>  </head>
 $bodytag  $bodytag
 <form name="modifyshown" method="post" action="/adm/feedback">  <form name="modifyshown" method="post" action="/adm/feedback">
Line 1754  $bodytag Line 1879  $bodytag
  <tr>   <tr>
   <td><b>$lt{'soor'}</b></td>    <td><b>$lt{'soor'}</b></td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td><b>$lt{'disp'}</b></td>    <td><b>$lt{'sprs'}</b></td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td><b>$lt{'actv'}</b></td>    <td><b>$lt{'spur'}</b></td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td><b>$lt{'spse'}</b></td>    <td><b>$lt{'spse'}</b></td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td><b>$lt{'psub'}</b></td>    <td><b>$lt{'psub'}</b></td>
  </tr>   </tr>
  <tr>   <tr>
   <td>    <td align="center">
    <select name="sortposts">     <select name="sortposts">
     <option value="ascdate" />Date order - oldest first      <option value="ascdate" selected="selected" />$sort_types{'ascdate'}
     <option value="descdate" />Date order - newest first      <option value="descdate" />$sort_types{'descdate'}
     <option value="thread" />Threaded      <option value="thread" />$sort_types{'thread'}
     <option value="subject" />By subject      <option value="subject" />$sort_types{'subject'}
     <option value="username" />By domain and username      <option value="username" />$sort_types{'username'}
     <option value="lastfirst" />By last name, first name      <option value="lastfirst" />$sort_types{'lastfirst'}
    </select>     </select>
   </td>    </td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td>    <td align="center">
    <select name="rolefilter" multiple="true" size="5">     <select name="statusfilter">
     <option value="all" />All users      <option value="all" selected="selected" />$status_types{'all'}
     <option value="st" />Students      <option value="Active" />$status_types{'Active'}
     <option value="cc" />Course Coordinators      <option value="Expired" />$status_types{'Expired'}
     <option value="in" />Instructors  
     <option value="ta" />TAs  
     <option value="pr" />Exam proctors  
     <option value="cr" />Custom roles  
    </select>     </select>
   </td>    </td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td>    <td align="center">
    <select name="statusfilter">     <select name="rolefilter" multiple="true" size="5">
     <option value="all" />Roles of any status      <option value="all" />$role_types{'all'}
     <option value="Active" />Only active roles      <option value="st" />$role_types{'st'}
     <option value="Expired" />Only inactive roles      <option value="cc" />$role_types{'cc'}
       <option value="in" />$role_types{'in'}
       <option value="ta" />$role_types{'ta'}
       <option value="ep" />$role_types{'ep'}
       <option value="ad" />$role_types{'ad'}
       <option value="cr" />$role_types{'cr'}
    </select>     </select>
   </td>    </td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td>    <td align="center">
    <select name="sectionpick" multiple="true" size="$numvisible">     <select name="sectionpick" multiple="true" size="$numvisible">
     $section_sel      $section_sel
    </select>     </select>
   </td>    </td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td><input type="checkbox" name="posterlist" value="$symb" />$lt{'shal'}</td>    <td><label><input type="checkbox" name="posterlist" value="$symb" />$lt{'shal'}</label></td>
  </tr>   </tr>
 </table>  </table>
 <br />  <br />
 <br />  <br />
 <input type="hidden" name="previous" value="$previous" />  <input type="hidden" name="previous" value="$previous" />
 <input type="hidden" name="applysort" value="$symb" />  <input type="hidden" name="applysort" value="$symb" />
 <input type="button" name="sub" value="Store Changes" onClick="javascript:document.modifyshown.submit()" />  <input type="button" name="sub" value="Store Changes" onClick="verifyFilter()" />
 <br />  <br />
 <br />  <br />
 </form>  </form>
Line 1818  END Line 1944  END
   
 sub print_showposters {  sub print_showposters {
     my ($r,$symb,$previous,$feedurl,$sortposts) = @_;      my ($r,$symb,$previous,$feedurl,$sortposts) = @_;
  # backward compatibility (bulletin boards used to be 'wrapped')  
     if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {      &Apache::loncommon::content_type($r,'text/html');
         $feedurl=~s|^/adm/wrapper||;      $r->send_http_header;
     }  
 # backward compatibility (bulletin boards used to be 'wrapped')      &Apache::lonenc::check_encrypt(\$symb);
     my $ressymb=$symb;      my $crs='/'.$env{'request.course.id'};
     if ($ressymb =~ /bulletin___\d+___/) {      if ($env{'request.course.sec'}) {
         unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {          $crs.='_'.$env{'request.course.sec'};
             $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;  
         }  
     }  
     my $crs='/'.$ENV{'request.course.id'};  
     if ($ENV{'request.course.sec'}) {  
         $crs.='_'.$ENV{'request.course.sec'};  
     }      }
     $crs=~s/\_/\//g;      $crs=~s/\_/\//g;
     my $seeid=&Apache::lonnet::allowed('rin',$crs);      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'}.'.domain'},
                           $ENV{'course.'.$ENV{'request.course.id'}.'.num'});                            $env{'course.'.$env{'request.course.id'}.'.num'});
     my %namesort = ();      my %namesort = ();
     my %postcounts = ();      my %postcounts = ();
     my %lt=&Apache::lonlocal::texthash(      my %lt=&Apache::lonlocal::texthash(
Line 1876  sub print_showposters { Line 1996  sub print_showposters {
             }              }
         }          }
     }      }
       my $html=&Apache::lonxml::xmlbegin();
     $r->print(<<END);      $r->print(<<END);
 <html>  $html
 <head>  <head>
 <title>$lt{'diso'}</title>  <title>$lt{'diso'}</title>
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
Line 1904  END Line 2025  END
                     next;                      next;
                 } else {                  } else {
                     $count ++;                      $count ++;
                     $r->print('<tr bgcolor="#ffffe6"><td align="right">'.$count.'</td><td align="center"><input name="stuinfo" type="checkbox" value="'.$_.'" /></td><td>'.$last.', '.$first.' ('.$uname.','.$udom.')</td><td>'.$postcounts{$_}.'</td></tr>');                      $r->print('<tr bgcolor="#ffffe6"><td align="right">'.$count.'</td><td align="center"><label><input name="stuinfo" type="checkbox" value="'.$_.'" /></td><td>'.$last.', '.$first.' ('.$uname.','.$udom.')</label></td><td>'.$postcounts{$_}.'</td></tr>');
                 }                  }
             }              }
         }          }
Line 1985  sub get_post_attachments { Line 2106  sub get_post_attachments {
     return;      return;
 }  }
   
 sub fail_redirect {;  sub fail_redirect {
   my ($r,$feedurl) = @_;    my ($r,$feedurl) = @_;
   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };    if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
     my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
     my $html=&Apache::lonxml::xmlbegin();
   $r->print (<<ENDFAILREDIR);    $r->print (<<ENDFAILREDIR);
 <html>  $html
 <head><title>Feedback not sent</title>  <head>
   <title>Feedback not sent</title>
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
 <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />  <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
 </head>  </head>
 <body bgcolor="#FFFFFF">  <body bgcolor="#FFFFFF">
 <img align="right" src="/adm/lonIcons/lonlogos.gif" />  <img align="right" src="$logo" />
 <b>Sorry, no recipients  ...</b>  <b>Sorry, no recipients  ...</b>
 <br /><a href="$feedurl">Continue</a>  <br /><a href="$feedurl">Continue</a>
 </body>  </body>
Line 2004  ENDFAILREDIR Line 2128  ENDFAILREDIR
 }  }
   
 sub redirect_back {  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 $sorttag = '';
   my $roletag = '';    my $roletag = '';
   my $statustag = '';    my $statustag = '';
Line 2012  sub redirect_back { Line 2136  sub redirect_back {
   my $userpicktag = '';    my $userpicktag = '';
   my $qrystr = '';    my $qrystr = '';
   my $prevtag = '';    my $prevtag = '';
  # backward compatibility (bulletin boards used to be 'wrapped')  
   if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {    &Apache::loncommon::content_type($r,'text/html');
       $feedurl=~s|^/adm/wrapper||;    $r->send_http_header;
   }  
     &dewrapper(\$feedurl);
   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };    if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
   if ($previous > 0) {    if ($previous > 0) {
       $qrystr = 'previous='.$previous;        $qrystr = 'previous='.$previous;
Line 2034  sub redirect_back { Line 2159  sub redirect_back {
           $feedurl .= '?'.$sortqry;            $feedurl .= '?'.$sortqry;
       }        }
       $sorttag = '<input type="hidden" name="sortposts" value="'.$sort.'" />';        $sorttag = '<input type="hidden" name="sortposts" value="'.$sort.'" />';
       if ( (defined($numpicks)) && ($numpicks > 0) ) {        if (defined($numpicks)) {
           my $userpickqry = 'totposters='.$numpicks;            my $userpickqry = 'totposters='.$numpicks;
           $feedurl .= '&'.$userpickqry;            $feedurl .= '&'.$userpickqry;
           $userpicktag = '<input type="hidden" name="totposters" value="'.$numpicks.'" />';            $userpicktag = '<input type="hidden" name="totposters" value="'.$numpicks.'" />';
       } else {        } else {
           my $roleqry = 'rolefilter='.$rolefilter;            if (ref($sectionpick) eq 'ARRAY') {
           $feedurl .= '&'.$roleqry;                $feedurl .= '&sectionpick=';
           $roletag = '<input type="hidden" name="rolefilter" value="'.$rolefilter.'" />';                $sectag .=  '<input type="hidden" name="sectionpick" value="';
                 foreach (@{$sectionpick}) {
                     $feedurl .= $_.',';
                     $sectag .= $_.',';
                 }
                 $feedurl =~ s/,$//;
                 $sectag =~ s/,$//;
                 $sectag .= '" />';
             } else {
                 $feedurl .= '&sectionpick='.$sectionpick;
                 $sectag = '<input type="hidden" name="sectionpick" value="'.$sectionpick.'" />';
             }
             if (ref($rolefilter) eq 'ARRAY') {
                 $feedurl .= '&rolefilter=';
                 $roletag .=  '<input type="hidden" name="rolefilter" value="';
                 foreach (@{$rolefilter}) {
                     $feedurl .= $_.',';
                     $roletag .= $_.',';
                 }
                 $feedurl =~ s/,$//;
                 $roletag =~ s/,$//;
                 $roletag .= '" />';
             } else {
                 $feedurl .= '&rolefilter='.$rolefilter;
                 $roletag = '<input type="hidden" name="rolefilter" value="'.$rolefilter.'" />';
             }
           $feedurl .= '&statusfilter='.$statusfilter;            $feedurl .= '&statusfilter='.$statusfilter;
           $statustag ='<input type="hidden" name="statusfilter" value="'.$statusfilter.'" />';            $statustag ='<input type="hidden" name="statusfilter" value="'.$statusfilter.'" />';
           $feedurl .= '&sectionpick='.$secpick;  
           $sectag = '<input type="hidden" name="sectionpick" value="'.$secpick.'" />';  
       }        }
   }    }
     $feedurl=&Apache::lonenc::check_encrypt($feedurl);
     my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
     my $html=&Apache::lonxml::xmlbegin();
   $r->print (<<ENDREDIR);    $r->print (<<ENDREDIR);
 <html>  $html
 <head>  <head>
 <title>Feedback sent</title>  <title>Feedback sent</title>
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
 <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />  <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
 </head>  </head>
 <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>  <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>
 <img align="right" src="/adm/lonIcons/lonlogos.gif" />  <img align="right" src="$logo" />
 $typestyle  $typestyle
 <b>Sent $sendsomething message(s), and $sendposts post(s).</b>  <b>Sent $sendsomething message(s), and $sendposts post(s).</b>
 <font color="red">$status</font>  <font color="red">$status</font>
Line 2078  sub no_redirect_back { Line 2229  sub no_redirect_back {
   my ($r,$feedurl) = @_;    my ($r,$feedurl) = @_;
   my $nofeed=&mt('Sorry, no feedback possible on this resource  ...');    my $nofeed=&mt('Sorry, no feedback possible on this resource  ...');
   my $continue=&mt('Continue');    my $continue=&mt('Continue');
     my $html=&Apache::lonxml::xmlbegin();
   $r->print (<<ENDNOREDIR);    $r->print (<<ENDNOREDIR);
 <html>  $html
 <head><title>Feedback not sent</title>  <head>
   <title>Feedback not sent</title>
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
 ENDNOREDIR  ENDNOREDIR
   
   if ($feedurl!~/^\/adm\/feedback/) {     if ($feedurl!~/^\/adm\/feedback/) { 
     $r->print('<meta HTTP-EQUIV="Refresh" CONTENT="2; url='.$feedurl.'">');        $r->print('<meta HTTP-EQUIV="Refresh" CONTENT="2; url='.
    &Apache::lonenc::check_encrypt($feedurl).'">');
   }    }
       $feedurl=&Apache::lonenc::check_encrypt($feedurl);
     my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
   $r->print (<<ENDNOREDIRTWO);    $r->print (<<ENDNOREDIRTWO);
 </head>  </head>
 <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { self.close(); }'>  <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { self.close(); }'>
 <img align="right" src="/adm/lonIcons/lonlogos.gif" />  <img align="right" src="$logo" />
 <b>$nofeed</b>  <b>$nofeed</b>
 <br /><a href="$feedurl">$continue</a>  <br /><a href="$feedurl">$continue</a>
 </body>  </body>
Line 2100  ENDNOREDIRTWO Line 2255  ENDNOREDIRTWO
 }  }
   
 sub screen_header {  sub screen_header {
     my ($feedurl) = @_;      my ($feedurl,$symb) = @_;
     my $msgoptions='';      my $msgoptions='';
     my $discussoptions='';      my $discussoptions='';
     unless (($ENV{'form.replydisc'}) || ($ENV{'form.editdisc'})) {      unless (($env{'form.replydisc'}) || ($env{'form.editdisc'})) {
  if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/)) {   if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/)) {
     $msgoptions=       $msgoptions= 
  '<p><input type="checkbox" name="author" /> '.   '<p><label><input type="checkbox" name="author" /> '.
  &mt('Feedback to resource author').'</p>';   &mt('Feedback to resource author').'</label></p>';
  }   }
  if (&feedback_available(1)) {   if (&feedback_available(1)) {
     $msgoptions.=      $msgoptions.=
  '<br /><input type="checkbox" name="question" /> '.   '<p><label><input type="checkbox" name="question" /> '.
  &mt('Question about resource content');   &mt('Question about resource content').'</label></p>';
  }   }
  if (&feedback_available(0,1)) {   if (&feedback_available(0,1)) {
     $msgoptions.=      $msgoptions.=
  '<br /><input type="checkbox" name="course" /> '.   '<p><label><input type="checkbox" name="course" /> '.
  &mt('Question/Comment/Feedback about course content');   &mt('Question/Comment/Feedback about course content').
    '</label></p>';
  }   }
  if (&feedback_available(0,0,1)) {   if (&feedback_available(0,0,1)) {
     $msgoptions.=      $msgoptions.=
  '<br /><input type="checkbox" name="policy" /> '.   '<p><label><input type="checkbox" name="policy" /> '.
  &mt('Question/Comment/Feedback about course policy');   &mt('Question/Comment/Feedback about course policy').
    '</label></p>';
  }   }
     }      }
     if ($ENV{'request.course.id'}) {      if ($env{'request.course.id'}) {
  if (&discussion_open() &&   if (&discussion_open(undef,$symb) &&
     &Apache::lonnet::allowed('pch',      &Apache::lonnet::allowed('pch',
      $ENV{'request.course.id'}.       $env{'request.course.id'}.
      ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {       ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
     $discussoptions='<input type="checkbox" name="discuss" onClick="this.form.anondiscuss.checked=false;" '.      $discussoptions='<label><input type="checkbox" name="discuss" onClick="this.form.anondiscuss.checked=false;" '.
  ($ENV{'form.replydisc'}?' checked="1"':'').' /> '.   ($env{'form.replydisc'}?' checked="1"':'').' /> '.
  &mt('Contribution to course discussion of resource');   &mt('Contribution to course discussion of resource');
     $discussoptions.='<br /><input type="checkbox" name="anondiscuss" onClick="this.form.discuss.checked=false;" /> '.      $discussoptions.='</label><br /><label><input type="checkbox" name="anondiscuss" onClick="this.form.discuss.checked=false;" /> '.
  &mt('Anonymous contribution to course discussion of resource').   &mt('Anonymous contribution to course discussion of resource').
  ' <i>('.&mt('name only visible to course faculty').')</i>';   ' <i>('.&mt('name only visible to course faculty').')</i></label>';
       }          }
     }      }
     if ($msgoptions) { $msgoptions='<h2><img src="/adm/lonMisc/feedback.gif" />'.&mt('Sending Messages').'</h2>'.$msgoptions; }      if ($msgoptions) { $msgoptions='<h2><img src="'.&Apache::loncommon::lonhttpdurl('/adm/lonMisc/feedback.gif').'" />'.&mt('Sending Messages').'</h2>'.$msgoptions; }
     if ($discussoptions) {       if ($discussoptions) { 
  $discussoptions='<h2><img src="/adm/lonMisc/chat.gif" />'.&mt('Discussion Contributions').'</h2>'.$discussoptions; }   $discussoptions='<h2><img src="'.&Apache::loncommon::lonhttpdurl('/adm/lonMisc/chat.gif').'" />'.&mt('Discussion Contributions').'</h2>'.$discussoptions; }
     return $msgoptions.$discussoptions;      return $msgoptions.$discussoptions;
 }  }
   
Line 2163  sub clear_out_html { Line 2320  sub clear_out_html {
 # Always allow the <m>-tag  # Always allow the <m>-tag
   my %html=(M=>1);    my %html=(M=>1);
 # Check if more is allowed  # Check if more is allowed
   my $cid=$ENV{'request.course.id'};    my $cid=$env{'request.course.id'};
   if (($ENV{"course.$cid.allow_limited_html_in_feedback"} =~ m/yes/i) ||    if (($env{"course.$cid.allow_limited_html_in_feedback"} =~ m/yes/i) ||
       ($override)) {        ($override)) {
       # allows <B> <I> <P> <A> <LI> <OL> <UL> <EM> <BR> <TT> <STRONG>         # allows <B> <I> <P> <A> <LI> <OL> <UL> <EM> <BR> <TT> <STRONG> 
       # <BLOCKQUOTE> <DIV .*> <DIV> <IMG> <M> <SPAN> <H1> <H2> <H3> <H4> <SUB>        # <BLOCKQUOTE> <DIV .*> <DIV> <IMG> <M> <SPAN> <H1> <H2> <H3> <H4> <SUB>
       # <SUP>        # <SUP>
       %html=(B=>1, I=>1, P=>1, A=>1, LI=>1, OL=>1, UL=>1, EM=>1,        %html=(B=>1, I=>1, P=>1, A=>1, LI=>1, OL=>1, UL=>1, EM=>1,
      BR=>1, TT=>1, STRONG=>1, BLOCKQUOTE=>1, DIV=>1, IMG=>1,       BR=>1, TT=>1, STRONG=>1, BLOCKQUOTE=>1, DIV=>1, IMG=>1,
      M=>1, SUB=>1, SUP=>1, SPAN=>1,        M=>1, ALGEBRA=>1, SUB=>1, SUP=>1, SPAN=>1, 
      H1=>1, H2=>1, H3=>1, H4=>1, H5=>1);       H1=>1, H2=>1, H3=>1, H4=>1, H5=>1);
   }    }
 # Do the substitution of everything that is not explicitly allowed  # Do the substitution of everything that is not explicitly allowed
Line 2185  sub clear_out_html { Line 2342  sub clear_out_html {
 sub assemble_email {  sub assemble_email {
   my ($feedurl,$message,$prevattempts,$usersaw,$useranswer)=@_;    my ($feedurl,$message,$prevattempts,$usersaw,$useranswer)=@_;
   my $email=<<"ENDEMAIL";    my $email=<<"ENDEMAIL";
 Refers to <a href="$feedurl">$feedurl</a>  
   
 $message  $message
 ENDEMAIL  ENDEMAIL
     my $citations=<<"ENDCITE";      my $citations=<<"ENDCITE";
Line 2209  sub secapply { Line 2364  sub secapply {
     my ($adr,$sections)=($rec=~/^([^\(]+)\(([^\)]+)\)/);      my ($adr,$sections)=($rec=~/^([^\(]+)\(([^\)]+)\)/);
     if ($sections) {      if ($sections) {
  foreach (split(/\;/,$sections)) {   foreach (split(/\;/,$sections)) {
             if (($_ eq $ENV{'request.course.sec'}) ||              if (($_ eq $env{'request.course.sec'}) ||
                 ($defaultflag && ($_ eq '*'))) {                  ($defaultflag && ($_ eq '*'))) {
                 return $adr;                   return $adr; 
             }              }
Line 2224  sub decide_receiver { Line 2379  sub decide_receiver {
   my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;    my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;
   my $typestyle='';    my $typestyle='';
   my %to=();    my %to=();
   if ($ENV{'form.author'}||$author) {    if ($env{'form.author'}||$author) {
     $typestyle.='Submitting as Author Feedback<br>';      $typestyle.='Submitting as Author Feedback<br>';
     $feedurl=~/^\/res\/(\w+)\/(\w+)\//;      $feedurl=~/^\/res\/(\w+)\/(\w+)\//;
     $to{$2.':'.$1}=1;      $to{$2.':'.$1}=1;
   }    }
   if ($ENV{'form.question'}||$question) {    if ($env{'form.question'}||$question) {
     $typestyle.='Submitting as Question<br>';      $typestyle.='Submitting as Question<br>';
     foreach (split(/\,/,      foreach (split(/\,/,
    $ENV{'course.'.$ENV{'request.course.id'}.'.question.email'})     $env{'course.'.$env{'request.course.id'}.'.question.email'})
      ) {       ) {
  my $rec=&secapply($_,$defaultflag);   my $rec=&secapply($_,$defaultflag);
         if ($rec) { $to{$rec}=1; }          if ($rec) { $to{$rec}=1; }
     }       } 
   }    }
   if ($ENV{'form.course'}||$course) {    if ($env{'form.course'}||$course) {
     $typestyle.='Submitting as Comment<br />';      $typestyle.='Submitting as Comment<br />';
     foreach (split(/\,/,      foreach (split(/\,/,
    $ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'})     $env{'course.'.$env{'request.course.id'}.'.comment.email'})
      ) {       ) {
  my $rec=&secapply($_,$defaultflag);   my $rec=&secapply($_,$defaultflag);
         if ($rec) { $to{$rec}=1; }          if ($rec) { $to{$rec}=1; }
     }       } 
   }    }
   if ($ENV{'form.policy'}||$policy) {    if ($env{'form.policy'}||$policy) {
     $typestyle.='Submitting as Policy Feedback<br />';      $typestyle.='Submitting as Policy Feedback<br />';
     foreach (split(/\,/,      foreach (split(/\,/,
    $ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'})     $env{'course.'.$env{'request.course.id'}.'.policy.email'})
      ) {       ) {
  my $rec=&secapply($_,$defaultflag);   my $rec=&secapply($_,$defaultflag);
         if ($rec) { $to{$rec}=1; }          if ($rec) { $to{$rec}=1; }
Line 2310  sub adddiscuss { Line 2465  sub adddiscuss {
  $realsymb=&Apache::lonnet::symbread($filename);   $realsymb=&Apache::lonnet::symbread($filename);
     }      }
     if (&discussion_open(undef,$realsymb) &&      if (&discussion_open(undef,$realsymb) &&
  &Apache::lonnet::allowed('pch',$ENV{'request.course.id'}.   &Apache::lonnet::allowed('pch',$env{'request.course.id'}.
         ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {          ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
   
     my %contrib=('message'      => $email,      my %contrib=('message'      => $email,
                  'sendername'   => $ENV{'user.name'},                   'sendername'   => $env{'user.name'},
                  'senderdomain' => $ENV{'user.domain'},                   'senderdomain' => $env{'user.domain'},
                  'screenname'   => $ENV{'environment.screenname'},                   'screenname'   => $env{'environment.screenname'},
                  'plainname'    => $ENV{'environment.firstname'}.' '.                   'plainname'    => $env{'environment.firstname'}.' '.
                    $ENV{'environment.middlename'}.' '.                     $env{'environment.middlename'}.' '.
                                    $ENV{'environment.lastname'}.' '.                                     $env{'environment.lastname'}.' '.
                                    $ENV{'enrironment.generation'},                                     $env{'enrironment.generation'},
                  'attachmenturl'=> $attachmenturl,                   'attachmenturl'=> $attachmenturl,
                  'subject'      => $subject);                   'subject'      => $subject);
     if ($ENV{'form.replydisc'}) {      if ($env{'form.replydisc'}) {
  $contrib{'replyto'}=(split(/\:\:\:/,$ENV{'form.replydisc'}))[1];   $contrib{'replyto'}=(split(/\:\:\:/,$env{'form.replydisc'}))[1];
     }      }
     if ($anon) {      if ($anon) {
  $contrib{'anonymous'}='true';   $contrib{'anonymous'}='true';
     }      }
     if (($symb) && ($email)) {      if (($symb) && ($email)) {
         if ($ENV{'form.editdisc'}) {          if ($env{'form.editdisc'}) {
             my %newcontrib = ();              my %newcontrib = ();
             $contrib{'ip'}=$ENV{'REMOTE_ADDR'};              $contrib{'ip'}=$ENV{'REMOTE_ADDR'};
             $contrib{'host'}=$Apache::lonnet::perlvar{'lonHostID'};              $contrib{'host'}=$Apache::lonnet::perlvar{'lonHostID'};
             $contrib{'timestamp'} = time;              $contrib{'timestamp'} = time;
             $contrib{'history'} = '';              $contrib{'history'} = '';
             my $numoldver = 0;              my $numoldver = 0;
             my ($oldsymb,$oldidx)=split(/\:\:\:/,$ENV{'form.editdisc'});              my ($oldsymb,$oldidx)=split(/\:\:\:/,$env{'form.editdisc'});
       &Apache::lonenc::check_decrypt(\$oldsymb);
             $oldsymb=~s|(bulletin___\d+___)adm/wrapper/|$1|;              $oldsymb=~s|(bulletin___\d+___)adm/wrapper/|$1|;
 # get timestamp for last post and history  # get timestamp for last post and history
             my %oldcontrib=&Apache::lonnet::restore($oldsymb,$ENV{'request.course.id'},              my %oldcontrib=&Apache::lonnet::restore($oldsymb,$env{'request.course.id'},
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                       $env{'course.'.$env{'request.course.id'}.'.domain'},
                      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});                       $env{'course.'.$env{'request.course.id'}.'.num'});
             if (defined($oldcontrib{$oldidx.':replyto'})) {              if (defined($oldcontrib{$oldidx.':replyto'})) {
                 $contrib{'replyto'} = $oldcontrib{$oldidx.':replyto'};                  $contrib{'replyto'} = $oldcontrib{$oldidx.':replyto'};
             }              }
Line 2377  sub adddiscuss { Line 2533  sub adddiscuss {
                 my $key = $oldidx.':'.&Apache::lonnet::escape($oldsymb).':'.$_;                                                                                                 my $key = $oldidx.':'.&Apache::lonnet::escape($oldsymb).':'.$_;                                                                               
                 $newcontrib{$key} = $contrib{$_};                  $newcontrib{$key} = $contrib{$_};
             }              }
             my $put_reply = &Apache::lonnet::putstore($ENV{'request.course.id'},              my $put_reply = &Apache::lonnet::putstore($env{'request.course.id'},
                   \%newcontrib,                    \%newcontrib,
                   $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                    $env{'course.'.$env{'request.course.id'}.'.domain'},
                   $ENV{'course.'.$ENV{'request.course.id'}.'.num'});                    $env{'course.'.$env{'request.course.id'}.'.num'});
             $status='Editing class discussion'.($anon?' (anonymous)':'');              $status='Editing class discussion'.($anon?' (anonymous)':'');
         } else {          } else {
            $status='Adding to class discussion'.($anon?' (anonymous)':'').': '.             $status='Adding to class discussion'.($anon?' (anonymous)':'').': '.
            &Apache::lonnet::store(\%contrib,$symb,$ENV{'request.course.id'},             &Apache::lonnet::store(\%contrib,$symb,$env{'request.course.id'},
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                       $env{'course.'.$env{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});       $env{'course.'.$env{'request.course.id'}.'.num'});
         }          }
         my %storenewentry=($symb => time);          my %storenewentry=($symb => time);
         $status.='<br />'.&mt('Updating discussion time').': '.          $status.='<br />'.&mt('Updating discussion time').': '.
         &Apache::lonnet::put('discussiontimes',\%storenewentry,          &Apache::lonnet::put('discussiontimes',\%storenewentry,
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                       $env{'course.'.$env{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});       $env{'course.'.$env{'request.course.id'}.'.num'});
     }      }
     my %record=&Apache::lonnet::restore('_discussion');      my %record=&Apache::lonnet::restore('_discussion');
     my ($temp)=keys %record;      my ($temp)=keys %record;
Line 2413  sub adddiscuss { Line 2569  sub adddiscuss {
   
 sub show_preview {  sub show_preview {
     my $r=shift;      my $r=shift;
     my $message=&clear_out_html($ENV{'form.comment'});      &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
       my $message=&clear_out_html($env{'form.comment'});
     $message=~s/\n/\<br \/\>/g;      $message=~s/\n/\<br \/\>/g;
     $message=&Apache::lonspeller::markeduptext($message);      $message=&Apache::lonspeller::markeduptext($message);
     $message=&Apache::lontexconvert::msgtexconverted($message);      $message=&Apache::lontexconvert::msgtexconverted($message);
     my $subject=&clear_out_html($ENV{'form.subject'});      my $subject=&clear_out_html($env{'form.subject'});
     $subject=~s/\n/\<br \/\>/g;      $subject=~s/\n/\<br \/\>/g;
     $subject=&Apache::lontexconvert::msgtexconverted($subject);      $subject=&Apache::lontexconvert::msgtexconverted($subject);
     $r->print('<table border="2"><tr><td>'.      my $html=&Apache::lonxml::xmlbegin();
        '<b>Subject:</b> '.$subject.'<br /><br />'.      $r->print($html.'<head>'.
        $message.'</td></tr></table>');        '</head><body><table border="2"><tr><td>'.
         '<b>Subject:</b> '.$subject.'<br /><br />'.
         $message.'</td></tr></table></body></html>');
 }  }
   
 sub generate_preview_button {  sub generate_preview_button {
Line 2439  ENDPREVIEW Line 2599  ENDPREVIEW
   
 sub modify_attachments {  sub modify_attachments {
     my ($r,$currnewattach,$currdelold,$symb,$idx,$attachmenturls)=@_;      my ($r,$currnewattach,$currdelold,$symb,$idx,$attachmenturls)=@_;
     my $orig_subject = &Apache::lonnet::unescape($ENV{'form.subject'});      my $orig_subject = &Apache::lonnet::unescape($env{'form.subject'});
     my $subject=&clear_out_html($orig_subject);      my $subject=&clear_out_html($orig_subject);
     $subject=~s/\n/\<br \/\>/g;      $subject=~s/\n/\<br \/\>/g;
     $subject=&Apache::lontexconvert::msgtexconverted($subject);      $subject=&Apache::lontexconvert::msgtexconverted($subject);
     my $timestamp=$ENV{'form.timestamp'};      my $timestamp=$env{'form.timestamp'};
     my $numoldver=$ENV{'form.numoldver'};      my $numoldver=$env{'form.numoldver'};
     my $bodytag=&Apache::loncommon::bodytag('Discussion Post Attachments',      my $bodytag=&Apache::loncommon::bodytag('Discussion Post Attachments',
                                           '','');                                            '','');
     my $msg = '';      my $msg = '';
Line 2453  sub modify_attachments { Line 2613  sub modify_attachments {
     if ($idx) {      if ($idx) {
         &extract_attachments($attachmenturls,$idx,$numoldver,\$msg,\%attachments,\%currattach,$currdelold);          &extract_attachments($attachmenturls,$idx,$numoldver,\$msg,\%attachments,\%currattach,$currdelold);
     }      }
       &Apache::lonenc::check_encrypt(\$symb);
       my $html=&Apache::lonxml::xmlbegin();
     $r->print(<<END);      $r->print(<<END);
 <html>  $html
 <head>  <head>
 <title>Managing Attachments</title>  <title>Managing Attachments</title>
 <script>  <script>
Line 2479  END Line 2641  END
                 foreach my $id (@currold) {                  foreach my $id (@currold) {
                     my $attachurl = &HTML::Entities::decode($attachments{$id}{'filename'});                       my $attachurl = &HTML::Entities::decode($attachments{$id}{'filename'}); 
                     $attachurl =~ m#/([^/]+)$#;                      $attachurl =~ m#/([^/]+)$#;
                     $r->print('<input type="checkbox" name="deloldattach" value="'.$id.'" />&nbsp;'.$1.'<br />'."\n");                      $r->print('<label><input type="checkbox" name="deloldattach" value="'.$id.'" />&nbsp;'.$1.'</label><br />'."\n");
                 }                  }
                 $r->print("<br />");                  $r->print("<br />");
             }              }
Line 2489  END Line 2651  END
         $r->print("The following attachments have been uploaded for inclusion with this posting.<br />Check the checkboxes for any you wish to remove<br />\n");          $r->print("The following attachments have been uploaded for inclusion with this posting.<br />Check the checkboxes for any you wish to remove<br />\n");
         foreach (@{$currnewattach}) {          foreach (@{$currnewattach}) {
             $_ =~ m#/([^/]+)$#;              $_ =~ m#/([^/]+)$#;
             $r->print('<input type="checkbox" name="delnewattach" value="'.$_.'" />&nbsp;'.$1.'<br />'."\n");              $r->print('<label><input type="checkbox" name="delnewattach" value="'.$_.'" />&nbsp;'.$1.'</label><br />'."\n");
         }          }
         $r->print("<br />");           $r->print("<br />"); 
     }      }
Line 2498  END Line 2660  END
    </td>     </td>
   </tr>    </tr>
  </table>   </table>
 <input type="hidden" name="subject" value="$ENV{'form.subject'}" />  <input type="hidden" name="subject" value="$env{'form.subject'}" />
 <input type="hidden" name="comment" value="$ENV{'form.comment'}" />  <input type="hidden" name="comment" value="$env{'form.comment'}" />
 <input type="hidden" name="timestamp" value="$ENV{'form.timestamp'}" />  <input type="hidden" name="timestamp" value="$env{'form.timestamp'}" />
 <input type="hidden" name="idx" value="$ENV{'form.idx'}" />  <input type="hidden" name="idx" value="$env{'form.idx'}" />
 <input type="hidden" name="numoldver" value="$ENV{'form.numoldver'}" />  <input type="hidden" name="numoldver" value="$env{'form.numoldver'}" />
 <input type="hidden" name="origpage" value="$ENV{'form.origpage'}" />  <input type="hidden" name="origpage" value="$env{'form.origpage'}" />
 <input type="hidden" name="anondiscuss" value="$ENV{'form.anondiscuss'}" />  <input type="hidden" name="anondiscuss" value="$env{'form.anondiscuss'}" />
 <input type="hidden" name="discuss" value="$ENV{'form.discuss'}" />  <input type="hidden" name="discuss" value="$env{'form.discuss'}" />
 END  END
     foreach (@{$currnewattach}) {      foreach (@{$currnewattach}) {
         $r->print('<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n");          $r->print('<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n");
Line 2524  END Line 2686  END
   
 sub process_attachments {  sub process_attachments {
     my ($currnewattach,$currdelold,$keepold) = @_;      my ($currnewattach,$currdelold,$keepold) = @_;
     if (exists($ENV{'form.currnewattach'})) {  
         if (ref($ENV{'form.currnewattach'}) eq 'ARRAY') {      @{$currnewattach}=
             @{$currnewattach} = @{$ENV{'form.currnewattach'}};   &Apache::loncommon::get_env_multiple('form.currnewattach');
         } else {      @{$currdelold}=
             $$currnewattach[0] = $ENV{'form.currnewattach'};   &Apache::loncommon::get_env_multiple('form.deloldattach');
         }      if (exists($env{'form.delnewattach'})) {
     }          my @currdelnew =
     if (exists($ENV{'form.deloldattach'})) {      &Apache::loncommon::get_env_multiple('form.delnewattach');
         if (ref($ENV{'form.deloldattach'}) eq 'ARRAY') {  
             @{$currdelold} = @{$ENV{'form.deloldattach'}};  
         } else {  
             $$currdelold[0] = $ENV{'form.deloldattach'};  
         }  
     }  
     if (exists($ENV{'form.delnewattach'})) {  
         my @currdelnew = ();  
         my @currnew = ();          my @currnew = ();
         if (ref($ENV{'form.delnewattach'}) eq 'ARRAY') {  
             @currdelnew = @{$ENV{'form.delnewattach'}};  
         } else {  
             $currdelnew[0] = $ENV{'form.delnewattach'};  
         }  
         foreach my $newone (@{$currnewattach}) {          foreach my $newone (@{$currnewattach}) {
             my $delflag = 0;              my $delflag = 0;
             foreach (@currdelnew) {              foreach (@currdelnew) {
Line 2560  sub process_attachments { Line 2709  sub process_attachments {
         }          }
         @{$currnewattach} = @currnew;          @{$currnewattach} = @currnew;
     }      }
     if (exists($ENV{'form.keepold'})) {      @{$keepold} = &Apache::loncommon::get_env_multiple('form.keepold');
         if (ref($ENV{'form.keepold'}) eq 'ARRAY') {  
             @{$keepold} = @{$ENV{'form.keepold'}};  
         } else {  
             $$keepold[0] = $ENV{'form.keepold'};  
         }  
     }  
 }  }
   
 sub generate_attachments_button {  sub generate_attachments_button {
Line 2666  sub construct_attachmenturl { Line 2809  sub construct_attachmenturl {
     my $newattachmenturl;      my $newattachmenturl;
     my $startnum = 0;      my $startnum = 0;
     my $currver = 0;      my $currver = 0;
     if (($ENV{'form.editdisc'}) && ($idx)) {      if (($env{'form.editdisc'}) && ($idx)) {
         my %contrib=&Apache::lonnet::restore($symb,$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'}.'.domain'},
                        $ENV{'course.'.$ENV{'request.course.id'}.'.num'});                         $env{'course.'.$env{'request.course.id'}.'.num'});
         $oldattachmenturl = $contrib{$idx.':attachmenturl'};          $oldattachmenturl = $contrib{$idx.':attachmenturl'};
         if ($contrib{$idx.':history'}) {          if ($contrib{$idx.':history'}) {
             if ($contrib{$idx.':history'} =~ /:/) {              if ($contrib{$idx.':history'} =~ /:/) {
Line 2716  sub construct_attachmenturl { Line 2859  sub construct_attachmenturl {
     }      }
     return $newattachmenturl;       return $newattachmenturl; 
 }  }
   
   sub has_discussion {
       my $resourcesref = shift;
       my $navmap = Apache::lonnavmaps::navmap->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 {  sub handler {
   my $r = shift;    my $r = shift;
Line 2728  sub handler { Line 2916  sub handler {
 # --------------------------- Get query string for limited number of parameters  # --------------------------- Get query string for limited number of parameters
   
   &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},    &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'};    if ($env{'form.discsymb'}) {
         my ($symb,$feedurl) = &get_feedurl_and_clean_symb($env{'form.discsymb'});
       my $readkey = $symb.'_read';        my $readkey = $symb.'_read';
       my %readinghash = ();  
       my $chgcount = 0;        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) {        foreach my $key (keys %env) {
           if ($key =~ m/^form\.postunread_(\d+)/) {            if ($key =~ m/^form\.postunread_(\d+)/) {
               if ($readinghash{$readkey} =~ /\.$1\./) {                if ($readinghash{$readkey} =~ /\.$1\./) {
                   $readinghash{$readkey} =~ s/\.$1\.//;                    $readinghash{$readkey} =~ s/\.$1\.//;
Line 2749  sub handler { Line 2937  sub handler {
           }            }
       }        }
       if ($chgcount > 0) {        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');        &redirect_back($r,$feedurl,&mt('Marked postings read/unread').'<br />',
       $r->send_http_header;       '0','0','',$env{'form.previous'},'','','',);
       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').'<br />','0','0','',$previous,'','','',);  
       return OK;        return OK;
   }    }
   if ($ENV{'form.allversions'}) {    if ($env{'form.allversions'}) {
       &Apache::loncommon::content_type($r,'text/html');        &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;        $r->send_http_header;
       my $bodytag=&Apache::loncommon::bodytag('Discussion Post Versions',        my $html=&Apache::lonxml::xmlbegin();
                                           '','');        my $bodytag=&Apache::loncommon::bodytag('Discussion Post Versions');
       $r->print (<<END);        $r->print(<<END);
 <html>  $html
 <head>  <head>
 <title>Post Versions</title>  <title>Post Versions</title>
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
 </head>  </head>
 $bodytag  $bodytag
 END  END
       my $crs='/'.$ENV{'request.course.id'};        my $crs='/'.$env{'request.course.id'};
       if ($ENV{'request.course.sec'}) {        if ($env{'request.course.sec'}) {
           $crs.='_'.$ENV{'request.course.sec'};            $crs.='_'.$env{'request.course.sec'};
       }        }
       $crs=~s/\_/\//g;        $crs=~s|_|/|g;
       my $seeid=&Apache::lonnet::allowed('rin',$crs);        my $seeid=&Apache::lonnet::allowed('rin',$crs);
       my ($symb,$idx)=split(/\:\:\:/,$ENV{'form.allversions'});        my ($symb,$idx)=split(/\:\:\:/,$env{'form.allversions'});
       my $ressymb=$symb;        ($symb)=&get_feedurl_and_clean_symb($symb);
       unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {  
           $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;  
       }  
       if ($idx > 0) {        if ($idx > 0) {
           my %messages = ();            my %messages = ();
           my %subjects = ();            my %subjects = ();
Line 2790  END Line 2972  END
           my %allattachments = ();            my %allattachments = ();
           my %imsfiles = ();            my %imsfiles = ();
           my ($screenname,$plainname);            my ($screenname,$plainname);
           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'}.'.domain'},
                $ENV{'course.'.$ENV{'request.course.id'}.'.num'});                             $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(&get_post_contents(\%contrib,$idx,$seeid,'allversions',\%messages,\%subjects,\%allattachments,\%attachmsgs,\%imsfiles,\$screenname,\$plainname));
           $r->print($discussion);  
       }        }
       return OK;        return OK;
   }    }
   if ($ENV{'form.posterlist'}) {    if ($env{'form.posterlist'}) {
       &Apache::loncommon::content_type($r,'text/html');        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.applysort'});
       $r->send_http_header;        &print_showposters($r,$symb,$env{'form.previous'},$feedurl,
       my $symb=$ENV{'form.posterlist'};   $env{'form.sortposts'});
       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);  
       return OK;        return OK;
   }    }
   if ($ENV{'form.userpick'}) {    if ($env{'form.userpick'}) {
       &Apache::loncommon::content_type($r,'text/html');        my @posters = &Apache::loncommon::get_env_multiple('form.stuinfo');
       $r->send_http_header;        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.userpick'});
       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 $numpicks = @posters;        my $numpicks = @posters;
       if (defined($ENV{'form.userpick'})) {        my %discinfo;
           my %discinfo = ();        $discinfo{$symb.'_userpick'} = join('&',@posters);
           $discinfo{$ressymb.'_userpick'} = join('&',@posters);        &Apache::lonnet::put('nohist_'.$env{'request.course.id'}.'_discuss',
           &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});     \%discinfo,$env{'user.domain'},$env{'user.name'});
       }        &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0',
       my $feedurl = &Apache::lonnet::clutter($url);       '',$env{'form.previous'},$env{'form.sortposts'},'','','',
  # backward compatibility (bulletin boards used to be 'wrapped')       $numpicks);
       if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {  
           $feedurl=~s|^/adm/wrapper||;  
       }  
       &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0','',$previous,$sort,'','','',$numpicks);  
       return OK;        return OK;
   }    }
   if ($ENV{'form.applysort'}) {    if ($env{'form.applysort'}) {
       &Apache::loncommon::content_type($r,'text/html');        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.applysort'});
       $r->send_http_header;        &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0',
       my $symb=$ENV{'form.applysort'};       '',$env{'form.previous'},$env{'form.sortposts'},
       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);       $env{'form.rolefilter'},$env{'form.statusfilter'},
       my $previous=$ENV{'form.previous'};       $env{'form.sectionpick'});
       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').'<br />','0','0','',$previous,$sort,$rolefilter,$statusfilter,$secpick);  
       return OK;        return OK;
   } elsif ($ENV{'form.sortfilter'}) {    } elsif ($env{'form.cmd'} eq 'sortfilter') {
       &Apache::loncommon::content_type($r,'text/html');        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});
       $r->send_http_header;        &print_sortfilter_options($r,$symb,$env{'form.previous'},$feedurl);
       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);  
       return OK;        return OK;
   } elsif ($ENV{'form.navmaps'}) {    } elsif ($env{'form.navtime'}) {
       my %discinfo = ();        my %discinfo = ();
       my @resources = ();        my @resources = ();
       if ($ENV{'form.navmaps'} =~ /:/) {        if (defined($env{'form.navmaps'})) {
           @resources = split/:/,$ENV{'form.navmaps'};            if ($env{'form.navmaps'} =~ /:/) {
                 @resources = split/:/,$env{'form.navmaps'};
             } else {
                 @resources = ("$env{'form.navmaps'}");
             }
       } else {        } else {
           @resources = ("$ENV{'form.navmaps'}");            &has_discussion(\@resources);
       }        }
       my $numitems = @resources;        my $numitems = @resources;
       my $feedurl = '/adm/navmaps';        my $feedurl = '/adm/navmaps';
       if ($ENV{'form.navurl'}) {        if ($env{'form.navurl'}) { $feedurl .= '?'.$env{'form.navurl'}; }
           $feedurl .= '?'.$ENV{'form.navurl'};  
       }  
       my %lt = &Apache::lonlocal::texthash(        my %lt = &Apache::lonlocal::texthash(
           'mnpa' => 'Marked "New" posts as read in a total of',            '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) {        foreach (@resources) {
 # backward compatibility (bulletin boards used to be 'wrapped')  # backward compatibility (bulletin boards used to be 'wrapped')
           my $ressymb=$_;            my $ressymb=$_;
     &Apache::lonenc::check_decrypt(\$ressymb);
           if ($ressymb =~ m/bulletin___\d+___/) {            if ($ressymb =~ m/bulletin___\d+___/) {
               unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {                unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
                   $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper/|;                    $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper/|;
               }                }
           }            }
           my $lastkey = $ressymb.'_lastread';            my $lastkey = $ressymb.'_lastread';
           $discinfo{$lastkey} = time;            $discinfo{$lastkey} = $env{'form.navtime'};
         }
         my $textline = "<b>$lt{'mnpa'} $numitems $lt{'robb'}</b>";
         if ($numitems > 0) {
             &Apache::lonnet::put('nohist_'.$env{'request.course.id'}.'_discuss',
        \%discinfo,$env{'user.domain'},$env{'user.name'});
         } else {
             $textline = "<b>$lt{'twnp'}</b>";
       }        }
       &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});  
       &Apache::loncommon::content_type($r,'text/html');        &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;        $r->send_http_header;
         my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
         my $html=&Apache::lonxml::xmlbegin();
       $r->print (<<ENDREDIR);        $r->print (<<ENDREDIR);
 <html>  $html
 <head>  <head>
 <title>New posts marked as read</title>  <title>New posts marked as read</title>
 <meta http-equiv="pragma" content="no-cache" />  <meta http-equiv="pragma" content="no-cache" />
 <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />  <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
 </head>  </head>
 <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>  <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>
 <img align="right" src="/adm/lonIcons/lonlogos.gif" />  <img align="right" src="$logo" />
 <b>$lt{'mnpa'} $numitems $lt{'robb'}</b>  $textline
 <form name="reldt" action="$feedurl" target="loncapaclient">  <form name="reldt" action="$feedurl" target="loncapaclient">
 </form>  </form>
 <br /><a href="$feedurl">Continue</a>  <br /><a href="$feedurl">Continue</a>
Line 2923  END Line 3069  END
 </html>  </html>
 ENDREDIR  ENDREDIR
       return OK;        return OK;
   } elsif ($ENV{'form.modifydisp'}) {    } elsif ($env{'form.modifydisp'}) {
       &Apache::loncommon::content_type($r,'text/html');        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.modifydisp'});
       $r->send_http_header;        my ($dispchgA,$dispchgB,$markchg,$toggchg) = 
       my $symb=$ENV{'form.modifydisp'};    split(/_/,$env{'form.changes'});
       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);        &print_display_options($r,$symb,$env{'form.previous'},$dispchgA,
       my $previous=$ENV{'form.previous'};       $dispchgB,$markchg,$toggchg,$feedurl);
       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;        return OK;
   } elsif (($ENV{'form.markondisp'}) || ($ENV{'form.markonread'}) || ($ENV{'form.allposts'}) || ($ENV{'form.onlyunread'}) || $ENV{'form.onlyunmark'} || $ENV{'form.toggoff'} || $ENV{'form.toggon'} ) {    } elsif ($env{'form.markondisp'} || $env{'form.markonread'} ||
       &Apache::loncommon::content_type($r,'text/html');     $env{'form.allposts'}   || $env{'form.onlyunread'} ||
       $r->send_http_header;     $env{'form.onlyunmark'} || $env{'form.toggoff'}    ||
       my $previous=$ENV{'form.previous'};     $env{'form.toggon'}     || $env{'form.markread'}) {
       my ($map,$ind,$url);        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});
       if ( ($ENV{'form.toggoff'}) || ($ENV{'form.toggon'}) ) {        my %discinfo;
 # ------------------------------ Modify setting for read/unread toggle for each post   # ------------------------ Modify setting for read/unread toggle for each post 
           my $symb=$ENV{'form.toggoff'}?$ENV{'form.toggoff'}:$ENV{'form.toggon'};        if ($env{'form.toggoff'}) { $discinfo{$symb.'_readtoggle'}=0; }
           my $ressymb = $symb;        if ($env{'form.toggon'})  { $discinfo{$symb.'_readtoggle'}=1; }
           ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);  # --------- Modify setting for identification of 'NEW' posts in this discussion
           unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {        if ($env{'form.markondisp'}) {
               $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;    $discinfo{$symb.'_lastread'} = time;
           }    $discinfo{$symb.'_markondisp'} = 1;
           my %discinfo = ();        }
           my $toggkey = $ressymb.'_readtoggle';        if ($env{'form.markonread'}) {
           if ($ENV{'form.toggon'}) {    if ( $env{'form.previous'} > 0 ) {
               $discinfo{$toggkey} = 1;        $discinfo{$symb.'_lastread'} = $env{'form.previous'};
           } elsif ($ENV{'form.toggoff'}) {    }
               $discinfo{$toggkey} = 0;    $discinfo{$symb.'_markondisp'} = 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 
 # ----------------------------------------------------------------- Modify display setting for this discussion         if ($env{'form.allposts'}) {
           my $symb;    $discinfo{$symb.'_showonlyunread'} = 0;
           if ($ENV{'form.allposts'}) {    $discinfo{$symb.'_showonlyunmark'} = 0;
               $symb = $ENV{'form.allposts'};        }
           } elsif ($ENV{'form.onlyunread'}) {        if ($env{'form.onlyunread'}) { $discinfo{$symb.'_showonlyunread'} = 1;  }
               $symb = $ENV{'form.onlyunread'};        if ($env{'form.onlyunmark'}) { $discinfo{$symb.'_showonlyunmark'} = 1;  }
           } else {  # ----------------------------------------------------- Mark new posts not NEW 
               $symb = $ENV{'form.onlyunmark'};        if ($env{'form.markread'})   { $discinfo{$symb.'_lastread'} = time; }
           }        &Apache::lonnet::put('nohist_'.$env{'request.course.id'}.'_discuss',
           my $ressymb = $symb;     \%discinfo,$env{'user.domain'},$env{'user.name'});
           ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);        my $previous=$env{'form.previous'};
           unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {        if ($env{'form.markondisp'}) { $previous=undef; }
               $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;        &redirect_back($r,$feedurl,&mt('Changed display status').'<br />',
           }       '0','0','',$previous);
           my %discinfo = ();        return OK;
           if ($ENV{'form.allposts'}) {    } elsif (($env{'form.hide'}) || ($env{'form.unhide'})) {
               $discinfo{$ressymb.'_showonlyunread'} = 0;  # ----------------------------------------------------------------- Hide/unhide
               $discinfo{$ressymb.'_showonlyunmark'} = 0;        my $entry=$env{'form.hide'}?$env{'form.hide'}:$env{'form.unhide'};
           } elsif ($ENV{'form.onlyunread'}) {        my ($symb,$idx)=split(/\:\:\:/,$entry);
               $discinfo{$ressymb.'_showonlyunread'} = 1;        ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);
           } else {  
               $discinfo{$ressymb.'_showonlyunmark'} = 1;        my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
           }                            $env{'course.'.$env{'request.course.id'}.'.domain'},
           &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});            $env{'course.'.$env{'request.course.id'}.'.num'});
   
         my $currenthidden=$contrib{'hidden'};
         my $currentstudenthidden=$contrib{'studenthidden'};
   
         my $crs='/'.$env{'request.course.id'};
         if ($env{'request.course.sec'}) {
     $crs.='_'.$env{'request.course.sec'};
       }        }
       if (($ENV{'form.markonread'}) || ($ENV{'form.allposts'}) || ($ENV{'form.onlyunread'}) || ($ENV{'form.onlyunmark'}) ||($ENV{'form.toggoff'}) || ($ENV{'form.toggon'}) ) {        $crs=~s/\_/\//g;
           &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'<br />','0','0','',$previous);        my $seeid=&Apache::lonnet::allowed('rin',$crs);
   
         if ($env{'form.hide'}) {
     $currenthidden.='.'.$idx.'.';
     unless ($seeid) {
         $currentstudenthidden.='.'.$idx.'.';
     }
       } else {        } else {
           &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'<br />','0','0');    $currenthidden=~s/\.$idx\.//g;
       }        }
       return OK;        my %newhash=('hidden' => $currenthidden);
   } elsif ($ENV{'form.markread'}) {        if ( ($env{'form.hide'}) && (!$seeid) ) {
 # ----------------------------------------------------------------- Mark new posts not NEW     $newhash{'studenthidden'} = $currentstudenthidden;
       &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|;  
       }        }
       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').'<br />','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);  
     my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);  
   
     my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},        &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                             $env{'course.'.$env{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});     $env{'course.'.$env{'request.course.id'}.'.num'});
   
           
     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);  
       
     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'});  
   
     &redirect_back($r,&Apache::lonnet::clutter($url),        &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
        &mt('Changed discussion status').'<br />','0','0','',$ENV{'form.previous'});       '0','0','',$env{'form.previous'});
   } elsif (($ENV{'form.threadedon'}) || ($ENV{'form.threadedoff'})) {        return OK;
       &Apache::loncommon::content_type($r,'text/html');    } elsif ($env{'form.cmd'}=~/^(threadedoff|threadedon)$/) {
       $r->send_http_header;        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});
       if ($ENV{'form.threadedon'}) {        if ($env{'form.cmd'} eq 'threadedon') {
   &Apache::lonnet::put('environment',{'threadeddiscussion' => 'on'});    &Apache::lonnet::put('environment',{'threadeddiscussion' => 'on'});
   &Apache::lonnet::appenv('environment.threadeddiscussion' => 'on');    &Apache::lonnet::appenv('environment.threadeddiscussion' => 'on');
       } else {        } else {
    &Apache::lonnet::del('environment',['threadeddiscussion']);     &Apache::lonnet::del('environment',['threadeddiscussion']);
   &Apache::lonnet::delenv('environment\.threadeddiscussion');    &Apache::lonnet::delenv('environment\.threadeddiscussion');
       }        }
       my $symb=$ENV{'form.threadedon'}?$ENV{'form.threadedon'}:$ENV{'form.threadedoff'};        &redirect_back($r,$feedurl,&mt('Changed discussion view mode').'<br />',
       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);       '0','0','',$env{'form.previous'});
       &redirect_back($r,&Apache::lonnet::clutter($url),        return OK;
      &mt('Changed discussion view mode').'<br />','0','0','',$ENV{'form.previous'});    } elsif ($env{'form.deldisc'}) {
   } elsif ($ENV{'form.deldisc'}) {  
 # --------------------------------------------------------------- Hide for good  # --------------------------------------------------------------- Hide for good
     &Apache::loncommon::content_type($r,'text/html');        my ($symb,$idx)=split(/\:\:\:/,$env{'form.deldisc'});
     $r->send_http_header;        ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);
         my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'},
     my $entry=$ENV{'form.deldisc'};                            $env{'course.'.$env{'request.course.id'}.'.domain'},
             $env{'course.'.$env{'request.course.id'}.'.num'});
     my ($symb,$idx)=split(/\:\:\:/,$entry);        my %newhash=('deleted' => $contrib{'deleted'}.".$idx.");
     my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);        &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},
      $env{'course.'.$env{'request.course.id'}.'.domain'},
     my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},     $env{'course.'.$env{'request.course.id'}.'.num'});
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},        &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});       '0','0','',$env{'form.previous'});
         return OK;
             } elsif ($env{'form.preview'}) {
     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').'<br />','0','0','',$ENV{'form.previous'});  
   } elsif ($ENV{'form.preview'}) {  
 # -------------------------------------------------------- User wants a preview  # -------------------------------------------------------- User wants a preview
       $r->content_type('text/html');  
       $r->send_http_header;  
       &show_preview($r);        &show_preview($r);
   } elsif ($ENV{'form.attach'}) {        return OK;
     } elsif ($env{'form.attach'}) {
 # -------------------------------------------------------- Work on attachments  # -------------------------------------------------------- Work on attachments
       &Apache::loncommon::content_type($r,'text/html');        &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;        $r->send_http_header;
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','addnewattach','delnewattach','timestamp','numoldver','idx','anondiscuss','discuss']);        &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','addnewattach','delnewattach','timestamp','numoldver','idx','anondiscuss','discuss']);
       my @currnewattach = ();        my (@currnewattach,@currdelold,@keepold);
       my @currdelold = ();  
       my @keepold = ();  
       &process_attachments(\@currnewattach,\@currdelold,\@keepold);        &process_attachments(\@currnewattach,\@currdelold,\@keepold);
       if (exists($ENV{'form.addnewattach.filename'})) {        if (exists($env{'form.addnewattach.filename'})) {
           unless (length($ENV{'form.addnewattach'})>131072) {            unless (length($env{'form.addnewattach'})>131072) {
               my $subdir = 'feedback/'.$ENV{'form.timestamp'};                my $subdir = 'feedback/'.$env{'form.timestamp'};
               my $newattachment=&Apache::lonnet::userfileupload('addnewattach',undef,$subdir);                my $newattachment=&Apache::lonnet::userfileupload('addnewattach',undef,$subdir);
               push @currnewattach, $newattachment;        push @currnewattach, $newattachment;
           }            }
       }        }
       my $attachmenturls = '';        my $attachmenturls;
       my $idx = $ENV{'form.idx'};        my ($symb) = &get_feedurl_and_clean_symb($env{'form.attach'});
       my $symb = $ENV{'form.attach'};        my $idx = $env{'form.idx'};
       if ($idx) {        if ($idx) {
           my %contrib=&Apache::lonnet::restore($symb,$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'}.'.domain'},
                          $ENV{'course.'.$ENV{'request.course.id'}.'.num'});                           $env{'course.'.$env{'request.course.id'}.'.num'});
           $attachmenturls = $contrib{$idx.':attachmenturl'};            $attachmenturls = $contrib{$idx.':attachmenturl'};
       }        }
       &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx,$attachmenturls);        &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx,
   } elsif ($ENV{'form.chgreads'}) {    $attachmenturls);
       &Apache::loncommon::content_type($r,'text/html');        return OK;
       $r->send_http_header;    } elsif ($env{'form.export'}) {
       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($ENV{'form.chgreads'});  
       &redirect_back($r,&Apache::lonnet::clutter($url),  
        &mt('Changed read status').'<br />','0','0');  
   } elsif ($ENV{'form.export'}) {  
       &Apache::loncommon::content_type($r,'text/html');        &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;        $r->send_http_header;
       my $symb=$ENV{'form.export'};        my ($symb,$feedurl) = &get_feedurl_and_clean_symb($env{'form.export'});
       my $mode;        my $mode='board';
       my $status='OPEN';        my $status='OPEN';
       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);        my $previous=$env{'form.previous'};
       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)$/) {        if ($feedurl =~ /\.(problem|exam|quiz|assess|survey|form|library)$/) {
           $mode='problem';            $mode='problem';
           $status=$Apache::inputtags::status[-1];            $status=$Apache::inputtags::status[-1];
Line 3175  ENDREDIR Line 3225  ENDREDIR
       return OK;        return OK;
   } else {    } else {
 # ------------------------------------------------------------- Normal feedback  # ------------------------------------------------------------- Normal feedback
   my $feedurl=$ENV{'form.postdata'};        my $feedurl=$env{'form.postdata'};
   $feedurl=~s/^http\:\/\///;        $feedurl=~s/^http\:\/\///;
   $feedurl=~s/^$ENV{'SERVER_NAME'}//;        $feedurl=~s/^$ENV{'SERVER_NAME'}//;
   $feedurl=~s/^$ENV{'HTTP_HOST'}//;        $feedurl=~s/^$ENV{'HTTP_HOST'}//;
   $feedurl=~s/\?.+$//;        $feedurl=~s/\?.+$//;
   
   my $symb;        my $symb;
   if ($ENV{'form.replydisc'}) {        if ($env{'form.replydisc'}) {
       $symb=(split(/\:\:\:/,$ENV{'form.replydisc'}))[0];    $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 ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);    my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
           $feedurl=&Apache::lonnet::clutter($url);    $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 ($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  # Go ahead with feedback, no ambiguous reference
     &Apache::loncommon::content_type($r,'text/html');        unless (
     $r->send_http_header;    (
        ($feedurl=~m:^/res:) && ($feedurl!~m:^/res/adm:)
     if (     ) 
       (    || 
        ($feedurl=~m:^/res:) && ($feedurl!~m:^/res/adm:)    ($env{'request.course.id'} && ($feedurl!~m:^/adm:))
       )     ||
       ||     ($env{'request.course.id'} && ($symb=~/^bulletin\_\_\_/))
       ($ENV{'request.course.id'} && ($feedurl!~m:^/adm:))    ) {
       ||    &Apache::loncommon::content_type($r,'text/html');
       ($ENV{'request.course.id'} && ($symb=~/^bulletin\_\_\_/))    $r->send_http_header;
      ) {  # Unable to give feedback
     &no_redirect_back($r,$feedurl);
         }
 # --------------------------------------------------- Print login screen header  # --------------------------------------------------- Print login screen header
     unless ($ENV{'form.sendit'}) {        unless ($env{'form.sendit'}) {
       my $options=&screen_header($feedurl);    &Apache::loncommon::content_type($r,'text/html');
       if ($options) {    $r->send_http_header;
         &mail_screen($r,$feedurl,$options);    my $options=&screen_header($feedurl,$symb);
       } else {    if ($options) {
  &fail_redirect($r,$feedurl);        &mail_screen($r,$feedurl,$options);
     } else {
         &fail_redirect($r,$feedurl);
     }
     return OK;
       }        }
     } else {  
               
 # Get previous user input  # Get previous user input
       my $prevattempts=&Apache::loncommon::get_previous_attempt(        my $prevattempts=&Apache::loncommon::get_previous_attempt(
             $symb,$ENV{'user.name'},$ENV{'user.domain'},                                     $symb,$env{'user.name'},$env{'user.domain'},
             $ENV{'request.course.id'});     $env{'request.course.id'});
   
 # Get output from resource  # Get output from resource
       my $usersaw=&resource_output($feedurl);        my $usersaw=&resource_output($feedurl);
Line 3245  ENDREDIR Line 3305  ENDREDIR
 # Get resource answer (need to allow student to view grades for this to work)  # Get resource answer (need to allow student to view grades for this to work)
       &Apache::lonnet::appenv(('allowed.vgr'=>'F'));        &Apache::lonnet::appenv(('allowed.vgr'=>'F'));
       my $useranswer=&Apache::loncommon::get_student_answers(        my $useranswer=&Apache::loncommon::get_student_answers(
                        $symb,$ENV{'user.name'},$ENV{'user.domain'},                                     $symb,$env{'user.name'},$env{'user.domain'},
        $ENV{'request.course.id'});                     $env{'request.course.id'});
       &Apache::lonnet::delenv('allowed.vgr');        &Apache::lonnet::delenv('allowed.vgr');
 # Get attachments, if any, and not too large  # Get attachments, if any, and not too large
       my $attachmenturl='';        my $attachmenturl='';
       if (($ENV{'form.origpage'}) || ($ENV{'form.editdisc'}) || ($ENV{'form.replydisc'})) {        if (($env{'form.origpage'}) || ($env{'form.editdisc'}) ||
           my ($symb,$idx);    ($env{'form.replydisc'})) {
           if ($ENV{'form.replydisc'}) {    my ($symb,$idx);
               ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'});    if ($env{'form.replydisc'}) {
           } elsif ($ENV{'form.editdisc'}) {        ($symb,$idx)=split(/\:\:\:/,$env{'form.replydisc'});
               ($symb,$idx)=split(/\:\:\:/,$ENV{'form.editdisc'});    } elsif ($env{'form.editdisc'}) {
           } elsif ($ENV{'form.origpage'}) {        ($symb,$idx)=split(/\:\:\:/,$env{'form.editdisc'});
               $symb = $ENV{'form.symb'};    } elsif ($env{'form.origpage'}) {
           }        $symb = $env{'form.symb'};
           my @currnewattach = ();    }
           my @deloldattach = ();    &Apache::lonenc::check_decrypt(\$symb);
           my @keepold = ();    my @currnewattach = ();
           &process_attachments(\@currnewattach,\@deloldattach,\@keepold);    my @deloldattach = ();
           $symb=~s|(bulletin___\d+___)adm/wrapper/|$1|;    my @keepold = ();
           $attachmenturl=&construct_attachmenturl(\@currnewattach,\@keepold,$symb,$idx);    &process_attachments(\@currnewattach,\@deloldattach,\@keepold);
       } elsif ($ENV{'form.attachment.filename'}) {    $symb=~s|(bulletin___\d+___)adm/wrapper/|$1|;
   unless (length($ENV{'form.attachment'})>131072) {    $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');        $attachmenturl=&Apache::lonnet::userfileupload('attachment',undef,'feedback');
   }    }
       }        }
 # Filter HTML out of message (could be nasty)  # Filter HTML out of message (could be nasty)
       my $message=&clear_out_html($ENV{'form.comment'});        my $message=&clear_out_html($env{'form.comment'});
   
 # Assemble email  # Assemble email
       my ($email,$citations)=&assemble_email($feedurl,$message,$prevattempts,        my ($email,$citations)=&assemble_email($feedurl,$message,$prevattempts,
           $usersaw,$useranswer);       $usersaw,$useranswer);
     
 # Who gets this?  # Who gets this?
       my ($typestyle,%to) = &decide_receiver($feedurl);        my ($typestyle,%to) = &decide_receiver($feedurl);
   
 # Actually send mail  # Actually send mail
       my ($status,$numsent)=&send_msg($feedurl,$email,$citations,        my ($status,$numsent)=&send_msg($feedurl,$email,$citations,
           $attachmenturl,%to);        $attachmenturl,%to);
   
 # Discussion? Store that.  # Discussion? Store that.
   
       my $numpost=0;        my $numpost=0;
       if ($ENV{'form.discuss'}) {        if ($env{'form.discuss'} || $env{'form.anondiscuss'}) {
           my $subject = &clear_out_html($ENV{'form.subject'});    my $subject = &clear_out_html($env{'form.subject'});
   $typestyle.=&adddiscuss($symb,$message,0,$attachmenturl,$subject);    my $anonmode=(defined($env{'form.anondiscuss'}));
   $numpost++;    $typestyle.=&adddiscuss($symb,$message,$anonmode,$attachmenturl,
       }    $subject);
   
       if ($ENV{'form.anondiscuss'}) {  
           my $subject = &clear_out_html($ENV{'form.subject'});  
   $typestyle.=&adddiscuss($symb,$message,1,$attachmenturl,$subject);  
   $numpost++;    $numpost++;
       }        }
     
   
 # Receipt screen and redirect back to where came from  # Receipt screen and redirect back to where came from
       &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$status,$ENV{'form.previous'});        &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;    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;  1;
 __END__  __END__

Removed from v.1.126  
changed lines
  Added in v.1.158


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.