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

version 1.129, 2004/11/11 22:19:53 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::lonnavmaps;
   use Apache::lonenc();
 use HTML::LCParser();  use HTML::LCParser();
 use Apache::lonspeller();  use Apache::lonspeller();
 use Cwd;  use Cwd;
Line 60  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|;  
         }  
     }  
     $ressymb=&Apache::lonenc::check_encrypt($ressymb);  
 # Get discussion display settings for this discussion  # Get discussion display settings for this discussion
     my $lastkey = $ressymb.'_lastread';      my $lastkey = $ressymb.'_lastread';
     my $showkey = $ressymb.'_showonlyunread';      my $showkey = $ressymb.'_showonlyunread';
Line 109  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 123  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 140  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 166  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 203  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 221  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 241  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 307  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 360  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='.$ressymb.'"><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 390  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 403  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 441  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 487  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 545  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 584  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 620  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 644  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='.
     $ressymb.':::" '.$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 689  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 714  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 822  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 886  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 900  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 950  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 1040  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 1178  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 1212  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 1233  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 1251  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 1287  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 1309  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 1384  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 1407  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 1416  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 1438  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 1479  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 1549  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 1641  $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 1663  $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 1680  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 1725  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 1733  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 1755  $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 1819  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 1877  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 1905  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 1986  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 2005  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 2013  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 2035  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);    $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 2080  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
   
Line 2091  ENDNOREDIR Line 2242  ENDNOREDIR
  &Apache::lonenc::check_encrypt($feedurl).'">');   &Apache::lonenc::check_encrypt($feedurl).'">');
   }    }
   $feedurl=&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 2103  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 2166  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 2188  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 2212  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 2227  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 2313  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 2380  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 2416  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 2442  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 2456  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 2482  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 2492  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 2501  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 2527  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 2563  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 2669  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 2736  sub has_discussion { Line 2876  sub has_discussion {
         }          }
     }      }
     return;      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 2749  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','navtime','navmaps','navurl','sortfilter','sortposts','applysort','rolefilter','statusfilter','sectionpick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export']);           ['hide','unhide','deldisc','postdata','preview','replydisc','editdisc','cmd','symb','onlyunread','allposts','onlyunmark','previous','markread','markonread','markondisp','toggoff','toggon','modifydisp','changes','navtime','navmaps','navurl','sortposts','applysort','rolefilter','statusfilter','sectionpick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export']);
   if ($ENV{'form.discsymb'}) {  
       my $symb = $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 2770  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 2811  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.navtime'}) {    } elsif ($env{'form.navtime'}) {
       my %discinfo = ();        my %discinfo = ();
       my @resources = ();        my @resources = ();
       if (defined($ENV{'form.navmaps'})) {        if (defined($env{'form.navmaps'})) {
           if ($ENV{'form.navmaps'} =~ /:/) {            if ($env{'form.navmaps'} =~ /:/) {
               @resources = split/:/,$ENV{'form.navmaps'};                @resources = split/:/,$env{'form.navmaps'};
           } else {            } else {
               @resources = ("$ENV{'form.navmaps'}");                @resources = ("$env{'form.navmaps'}");
           }            }
       } else {        } else {
           &has_discussion(\@resources);            &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.',
Line 2921  END Line 3032  END
       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} = $ENV{'form.navtime'};            $discinfo{$lastkey} = $env{'form.navtime'};
       }        }
       my $textline = "<b>$lt{'mnpa'} $numitems $lt{'robb'}</b>";        my $textline = "<b>$lt{'mnpa'} $numitems $lt{'robb'}</b>";
       if ($numitems > 0) {        if ($numitems > 0) {
           &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'});
       } else {        } else {
           $textline = "<b>$lt{'twnp'}</b>";            $textline = "<b>$lt{'twnp'}</b>";
       }        }
       &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" />
 $textline  $textline
 <form name="reldt" action="$feedurl" target="loncapaclient">  <form name="reldt" action="$feedurl" target="loncapaclient">
 </form>  </form>
Line 2954  $textline Line 3069  $textline
 </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);        &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},
     my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);                             $env{'course.'.$env{'request.course.id'}.'.domain'},
      $env{'course.'.$env{'request.course.id'}.'.num'});
   
     my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},        &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},       '0','0','',$env{'form.previous'});
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});        return OK;
     } elsif ($env{'form.cmd'}=~/^(threadedoff|threadedon)$/) {
                 my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});
     my $currenthidden=$contrib{'hidden'};        if ($env{'form.cmd'} eq 'threadedon') {
     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),  
        &mt('Changed discussion status').'<br />','0','0','',$ENV{'form.previous'});  
   } elsif (($ENV{'form.threadedon'}) || ($ENV{'form.threadedoff'})) {  
       &Apache::loncommon::content_type($r,'text/html');  
       $r->send_http_header;  
       if ($ENV{'form.threadedon'}) {  
   &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 3206  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);    my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
       $feedurl=&Apache::lonnet::clutter($url);    $feedurl=&Apache::lonnet::clutter($url);
   } elsif ($ENV{'form.editdisc'}) {        } elsif ($env{'form.editdisc'}) {
       $symb=(split(/\:\:\:/,$ENV{'form.editdisc'}))[0];    $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.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 3276  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.129  
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.