Diff for /loncom/interface/lonfeedback.pm between versions 1.168 and 1.242

version 1.168, 2005/09/20 07:52:03 version 1.242, 2007/02/23 00:39:31
Line 39  use Apache::lonnet; Line 39  use Apache::lonnet;
 use Apache::lonhtmlcommon();  use Apache::lonhtmlcommon();
 use Apache::lonnavmaps;  use Apache::lonnavmaps;
 use Apache::lonenc();  use Apache::lonenc();
   use Apache::lonrss();
 use HTML::LCParser();  use HTML::LCParser();
 use Apache::lonspeller();  use Apache::lonspeller();
   use Apache::longroup;
 use Cwd;  use Cwd;
   use LONCAPA;
   
 sub discussion_open {  sub discussion_open {
     my ($status,$symb)=@_;      my ($status,$symb)=@_;
       if ($env{'request.role.adv'}) { return 1; }
     if (defined($status) &&      if (defined($status) &&
  !($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'   !($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
   || $status eq 'OPEN')) {    || $status eq 'OPEN')) {
Line 69  sub discussion_visible { Line 73  sub discussion_visible {
 }  }
   
 sub list_discussion {  sub list_discussion {
     my ($mode,$status,$ressymb,$imsextras)=@_;      my ($mode,$status,$ressymb,$imsextras,$group)=@_;
       unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); }
       unless ($ressymb) { return ''; }
       $ressymb=&wrap_symb($ressymb);
     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'}) {
Line 81  sub list_discussion { Line 88  sub list_discussion {
             $outputtarget = 'export';              $outputtarget = 'export';
         }          }
     }      }
     if (not &discussion_visible($status)) { return ''; }      if (not &discussion_visible($status)) {
           if ($mode ne 'board') {
               &Apache::lonenc::check_encrypt(\$ressymb); 
               return &send_message_link($ressymb);
           }
       }
       if ($group ne '' && $mode eq 'board') {
           if (&check_group_priv($group,'vgb') ne 'ok') {
               return '';
           }
       }
   
       my ($blocked,$blocktext) = 
           &Apache::loncommon::blocking_status('boards');
       if ($blocked) {
           &Apache::lonenc::check_encrypt(\$ressymb);
           if ($mode ne 'board') {
               $blocktext.='<br />'.&send_message_link($ressymb);
           }
           return $blocktext; 
       }
   
     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; }
Line 92  sub list_discussion { Line 120  sub list_discussion {
  $crs.='_'.$env{'request.course.sec'};   $crs.='_'.$env{'request.course.sec'};
     }      }
     $crs=~s/\_/\//g;      $crs=~s/\_/\//g;
     unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); }  
     unless ($ressymb) { return ''; }  
     $ressymb=&wrap_symb($ressymb);  
     my $encsymb=&Apache::lonenc::check_encrypt($ressymb);      my $encsymb=&Apache::lonenc::check_encrypt($ressymb);
     my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)      my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
   && ($ressymb=~/\.(problem|exam|quiz|assess|survey|form|task)$/));    && ($ressymb=~/\.(problem|exam|quiz|assess|survey|form|task)$/));
Line 113  sub list_discussion { Line 138  sub list_discussion {
     my $toggkey = $ressymb.'_readtoggle';      my $toggkey = $ressymb.'_readtoggle';
     my $readkey = $ressymb.'_read';      my $readkey = $ressymb.'_read';
     $ressymb=$encsymb;      $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_'.$cid.'_discuss',[$lastkey,$showkey,$markkey,$visitkey,$ondispkey,$userpickkey,$toggkey,$readkey],$env{'user.domain'},$env{'user.name'});
     my %discinfo = ();      my %discinfo = ();
     my $showonlyunread = 0;      my $showonlyunread = 0;
     my $showunmark = 0;       my $showunmark = 0; 
Line 122  sub list_discussion { Line 147  sub list_discussion {
     my $previous = 0;      my $previous = 0;
     my $visit = 0;      my $visit = 0;
     my $newpostsflag = 0;      my $newpostsflag = 0;
     my @posters = split/\&/,$dischash{$userpickkey};      my @posters = split(/\&/,$dischash{$userpickkey});
   
 # 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','grouppick','totposters']);
     my $sortposts = $env{'form.sortposts'};      my $sortposts = $env{'form.sortposts'};
     my $statusfilter = $env{'form.statusfilter'};      my $statusfilter = $env{'form.statusfilter'};
     my @sectionpick = ();      my @sectionpick = split(/,/,$env{'form.sectionpick'});
     if ($env{'form.sectionpick'} =~ /,/) {      my @grouppick   = split(/,/,$env{'form.grouppick'});
         @sectionpick = split/,/,$env{'form.sectionpick'};      my @rolefilter  = split(/,/,$env{'form.rolefilter'});
     } 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'};      my $totposters = $env{'form.totposters'};
     $previous = $env{'form.previous'};      $previous = $env{'form.previous'};
     if ($previous > 0) {      if ($previous > 0) {
Line 150  sub list_discussion { Line 167  sub list_discussion {
         }          }
     }      }
   
       my $cdom = $env{'course.'.$cid.'.domain'};
       my $cnum = $env{'course.'.$cid.'.num'};
   
 # 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 = ();
       my ($classgroups,$studentgroups);
     if ($env{'form.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',$cdom,$cnum);
         foreach (keys %roleshash) {          foreach my $rolekey (keys(%roleshash)) {
             my ($role,$uname,$udom,$sec) = split/:/,$_;              my ($role,$uname,$udom,$sec) = split(/:/,$rolekey);
             if ($role =~ /^cr/) {              if ($role =~ /^cr/) {
                 $role = 'cr';                  $role = 'cr';
             }              }
             my ($end,$start) = split/:/,$roleshash{$_};              my ($end,$start) = split(/:/,$roleshash{$rolekey});
             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';
             }              }
             if ($uname && $udom) {               if ($uname && $udom) { 
                 push @{$roleinfo{$uname.':'.$udom}}, $role.':'.$sec.':'.$status;                  push(@{$roleinfo{$uname.':'.$udom}}, $role.':'.$sec.':'.$status);
             }              }
         }          }
         my ($classlist) = &Apache::loncoursedata::get_classlist(          my ($classlist,$keylist) =
                               $env{'request.course.id'},                           &Apache::loncoursedata::get_classlist($cdom,$cnum);
                               $env{'course.'.$env{'request.course.id'}.'.domain'},  
                               $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) {
             my ($section,$status) = ($data->[$sec_index],              my ($section,$status) = ($data->[$sec_index],
                                  $data->[$status_index]);                                   $data->[$status_index]);
             push @{$roleinfo{$student}}, 'st:'.$section.':'.$status;              push(@{$roleinfo{$student}}, 'st:'.$section.':'.$status);
         }          }
    ($classgroups,$studentgroups) = 
       &Apache::loncoursedata::get_group_memberships($classlist,$keylist,
     $cdom,$cnum);
     }      }
   
 # Get discussion display default settings for user  # Get discussion display default settings for user
Line 220  sub list_discussion { Line 242  sub list_discussion {
     }      }
     $visit ++;      $visit ++;
   
     my $seeid=&Apache::lonnet::allowed('rin',$crs);      my $seeid;
       if (($group ne '') && ($mode eq 'board') && 
           ($ressymb =~ m|^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|)) {
           if (&check_group_priv($group,'dgp') eq 'ok') {
               $seeid = 1;
           }
       } else {
           $seeid=&Apache::lonnet::allowed('rin',$crs);
       }
     my @discussionitems=();      my @discussionitems=();
     my %shown = ();      my %shown = ();
     my @posteridentity=();      my @posteridentity=();
Line 235  sub list_discussion { Line 265  sub list_discussion {
     my %notshown = ();      my %notshown = ();
     my %newitem = ();      my %newitem = ();
     my $maxdepth=0;      my $maxdepth=0;
       my %anonhash=();
       my $anoncnt=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' ) {
Line 245  sub list_discussion { Line 276  sub list_discussion {
     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_'.$cid.'_discuss',\%discinfo,$env{'user.domain'},$env{'user.name'});
     &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$encsymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,$statusfilter,$toggkey,$outputtarget);      &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,\@grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,\%anonhash,$anoncnt,$group);
   
     my $discussion='';      my $discussion='';
     my $manifestfile;      my $manifestfile;
Line 274  sub list_discussion { Line 305  sub list_discussion {
         'disp' => 'Display',          'disp' => 'Display',
         'nolo' => 'Not new',          'nolo' => 'Not new',
         'togg' => 'Toggle read/unread',          'togg' => 'Toggle read/unread',
           'aner' => 'An error occurred opening the manifest file.',
           'difo' => 'Discussion for',
           'aerr' => 'An error occurred opening the export file for posting',
           'aysu' => 'Are you sure you want to delete this post?',
           'dpwn' => 'Deleted posts will no longer be visible to you and other students',
           'bwco' => 'but will continue to be visible to your instructor',
           'depo' => 'Deleted posts will no longer be visible to you or anyone else.',
     );      );
   
     my $currdisp = $lt{'allposts'};      my $currdisp = $lt{'allposts'};
Line 319  sub list_discussion { Line 357  sub list_discussion {
     if ($newpostsflag) {      if ($newpostsflag) {
         $chglink .= '&previous='.$prevread;          $chglink .= '&previous='.$prevread;
     }      }
       $chglink.=&group_args($group);
   
     if ($visible) {      if ($visible) {
 # Print the discusssion  # Print the discusssion
Line 367  identifier="MANIFEST-$ressymb" xsi:schem Line 406  identifier="MANIFEST-$ressymb" xsi:schem
 imscp_v1p1.xsd http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2p2.xsd">  imscp_v1p1.xsd http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2p2.xsd">
   <organizations default="$ressymb">    <organizations default="$ressymb">
     <organization identifier="$ressymb">      <organization identifier="$ressymb">
       <title>Discussion for $ressymb</title>\n|;        <title>$lt{'difo'} $ressymb</title>\n|;
             } else {              } else {
                 $discussion .= 'An error occurred opening the manifest file.<br />';                  $discussion .= $lt{'aner'}.'<br />';
             }              }
  } else {   } else {
             my $colspan=$maxdepth+1;              my $colspan=$maxdepth+1;
             $discussion.= qq|              $discussion.= qq|
 <script>  <script>
    function studentdelete (symb,idx,newflag,previous) {     function verifydelete (caller,symb,idx,newflag,previous,groupparm) {
        var symbparm = symb+':::'+idx         var symbparm = symb+':::'+idx
        var prevparm = ""         var prevparm = ""
        if (newflag == 1) {         if (newflag == 1) {
            prevparm = "&previous="+previous             prevparm = "&previous="+previous
        }         }
        if (confirm("Are you sure you want to delete this post?\\nDeleted posts will no longer be visible to you and other students,\\nbut will continue to be visible to your instructor")) {         if (caller == 'studentdelete') {
            document.location.href = "/adm/feedback?hide="+symbparm+prevparm             if (confirm("$lt{'aysu'}\\n$lt{'dpwn'},\\n$lt{'bwco'}")) {
        }                   document.location.href = "/adm/feedback?hide="+symbparm+prevparm+groupparm
              }
          } else {
              if (caller == 'seeiddelete') {
                  if (confirm("$lt{'aysu'}\\n$lt{'depo'}")) {
                      document.location.href = "/adm/feedback?deldisc="+symbparm+prevparm+groupparm
                  }
              }
          }
    }     }
 </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 .= &action_links_bar($colspan,$ressymb,$visible,
  '<table border="0" width="100%" bgcolor="#DDDDBB"><tr>';                                               $newpostsflag,$group,
     if ($visible>2) {                                               $prevread,$markondisp);
  $discussion.='<td align="left">'.              my $escsymb=&escape($ressymb);
     '<a href="/adm/feedback?cmd=threadedon&amp;symb='.$ressymb;              my $numhidden = keys(%notshown);
  if ($newpostsflag) {  
     $discussion .= '&previous='.$prevread;  
  }  
  $discussion .='">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.  
     '<a href="/adm/feedback?cmd=threadedoff&amp;symb='.$ressymb;  
  if ($newpostsflag) {  
     $discussion .= '&previous='.$prevread;  
  }  
  $discussion .='">'.&mt('Chronological View').'</a>&nbsp;&nbsp;  
                               <a href= "/adm/feedback?cmd=sortfilter&amp;symb='.$ressymb;  
                 if ($newpostsflag) {  
                     $discussion .= '&previous='.$prevread;  
                 }  
                 $discussion .='">'.&mt('Sorting/Filtering options').'</a>&nbsp;&nbsp';  
             } else {  
                 $discussion .= '<td align="left">';  
             }  
             $discussion .='<a href= "/adm/feedback?export='.$ressymb;  
             if ($newpostsflag) {  
                 $discussion .= '&previous='.$prevread;  
             }  
             $discussion .= '">'.&mt('Export').'?</a>&nbsp;&nbsp;</td>';  
     if ($newpostsflag) {  
  if (!$markondisp) {  
     $discussion .='<td align="right"><a href="/adm/feedback?markread=1&amp;symb='.$ressymb.'">'.&mt('Mark NEW posts no longer new').'</a>&nbsp;&nbsp;';  
  } else {  
     $discussion .= '<td>&nbsp;</td>';  
  }  
     } else {  
  $discussion .= '<td>&nbsp;</td>';  
     }  
     $discussion .= '</tr></table></td></tr>';  
   
             my $numhidden = keys %notshown;  
             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=1&amp;symb='.$ressymb;                           '<a href="/adm/feedback?allposts=1&amp;symb='.$escsymb;
                 if ($newpostsflag) {                  if ($newpostsflag) {
                     $discussion .= '&previous='.$prevread;                      $discussion .= '&previous='.$prevread;
                 }                  }
    $discussion .= &group_args($group);
                 $discussion .= '">'.&mt('Show all posts').'</a> '.&mt('to display').' '.                  $discussion .= '">'.&mt('Show all posts').'</a> '.&mt('to display').' '.
                          $numhidden.' ';                           $numhidden.' ';
                 if ($showunmark) {                  if ($showunmark) {
Line 448  imscp_v1p1.xsd http://www.imsglobal.org/ Line 462  imscp_v1p1.xsd http://www.imsglobal.org/
 # Choose sort mechanism  # Choose sort mechanism
         my @showposts = ();          my @showposts = ();
         if ($sortposts eq 'descdate') {          if ($sortposts eq 'descdate') {
             @showposts = (sort { $b <=> $a } keys %alldiscussion);              @showposts = (sort { $b <=> $a } keys(%alldiscussion));
         } elsif ($sortposts eq 'thread') {          } elsif ($sortposts eq 'thread') {
             @showposts = (sort { $a <=> $b } keys %alldiscussion);              @showposts = (sort { $a <=> $b } keys(%alldiscussion));
         } elsif ($sortposts eq 'subject') {          } elsif ($sortposts eq 'subject') {
             foreach (sort keys %subjectsort) {              foreach my $key (sort(keys(%subjectsort))) {
                 push @showposts, @{$subjectsort{$_}};                  push(@showposts, @{$subjectsort{$key}});
             }              }
         } elsif ($sortposts eq 'username') {          } elsif ($sortposts eq 'username') {
             foreach my $domain (sort keys %usernamesort) {              foreach my $domain (sort(keys(%usernamesort))) {
                 foreach (sort keys %{$usernamesort{$domain}}) {                  foreach my $key (sort(keys(%{$usernamesort{$domain}}))) {
                     push @showposts, @{$usernamesort{$domain}{$_}};                      push(@showposts, @{$usernamesort{$domain}{$key}});
                 }                  }
             }              }
         } elsif ($sortposts eq 'lastfirst') {          } elsif ($sortposts eq 'lastfirst') {
             foreach my $last (sort keys %namesort) {              foreach my $last (sort(keys(%namesort))) {
                  foreach (sort keys %{$namesort{$last}}) {                   foreach my $key (sort(keys(%{$namesort{$last}}))) {
                      push @showposts, @{$namesort{$last}{$_}};                       push(@showposts, @{$namesort{$last}{$key}});
                  }                   }
             }              }
         } else {          } else {
             @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 my $post (@showposts) {
             unless (($sortposts eq 'thread') || (($sortposts eq '') && ($env{'environment.threadeddiscussion'})) || ($outputtarget eq 'export')) {              unless (($sortposts eq 'thread') || (($sortposts eq '') && ($env{'environment.threadeddiscussion'})) || ($outputtarget eq 'export')) {
                 $alldiscussion{$_} = $_;                  $alldiscussion{$post} = $post;
             }              }
             unless ( ($notshown{$alldiscussion{$_}} eq '1') || ($shown{$alldiscussion{$_}} == 0) ) {              unless ( ($notshown{$alldiscussion{$post}} eq '1') || ($shown{$alldiscussion{$post}} == 0) ) {
                 if ($outputtarget ne 'tex' && $outputtarget ne 'export') {                  if ($outputtarget ne 'tex' && $outputtarget ne 'export') {
     $discussion.="\n<tr>";      $discussion.="\n<tr>";
  }   }
         my $thisdepth=$depth[$alldiscussion{$_}];          my $thisdepth=$depth[$alldiscussion{$post}];
                 if ($outputtarget ne 'tex' && $outputtarget ne 'export') {                  if ($outputtarget ne 'tex' && $outputtarget ne 'export') {
     for (1..$thisdepth) {      for (1..$thisdepth) {
  $discussion.='<td>&nbsp;&nbsp;&nbsp;</td>';   $discussion.='<td>&nbsp;&nbsp;&nbsp;</td>';
Line 489  imscp_v1p1.xsd http://www.imsglobal.org/ Line 503  imscp_v1p1.xsd http://www.imsglobal.org/
         my $colspan=$maxdepth-$thisdepth+1;          my $colspan=$maxdepth-$thisdepth+1;
                 if ($outputtarget eq 'tex') {                  if ($outputtarget eq 'tex') {
     #cleanup block      #cleanup block
     $discussionitems[$alldiscussion{$_}]=~s/<table([^>]*)>/<table TeXwidth="90 mm">/;      $discussionitems[$alldiscussion{$post}]=~s/<table([^>]*)>/<table TeXwidth="90 mm">/;
     $discussionitems[$alldiscussion{$_}]=~s/<tr([^>]*)><td([^>]*)>/<tr><td TeXwidth="20 mm" align="left">/;      $discussionitems[$alldiscussion{$post}]=~s/<tr([^>]*)><td([^>]*)>/<tr><td TeXwidth="20 mm" align="left">/;
                     my $threadinsert='';                      my $threadinsert='';
                     if ($thisdepth > 0) {                      if ($thisdepth > 0) {
  $threadinsert='<br /><strong>Reply: '.$thisdepth.'</strong>';   $threadinsert='<br /><strong>Reply: '.$thisdepth.'</strong>';
     }      }
     $discussionitems[$alldiscussion{$_}]=~s/<\/td><td([^>]*)>/$threadinsert<\/td><td TeXwidth="65 mm" align="left">/;      $discussionitems[$alldiscussion{$post}]=~s/<\/td><td([^>]*)>/$threadinsert<\/td><td TeXwidth="65 mm" align="left">/;
     $discussionitems[$alldiscussion{$_}]=~s/<a([^>]+)>(Edit|Hide|Delete|Reply|Submissions)<\/a>//g;      $discussionitems[$alldiscussion{$post}]=~s/<a([^>]+)>(Edit|Hide|Delete|Reply|Submissions)<\/a>//g;
                     $discussionitems[$alldiscussion{$_}]=~s/(<b>|<\/b>|<\/a>|<a([^>]+)>)//g;                      $discussionitems[$alldiscussion{$post}]=~s/(<b>|<\/b>|<\/a>|<a([^>]+)>)//g;
   
     $discussionitems[$alldiscussion{$_}]='<tex>\vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}</tex>'.$discussionitems[$alldiscussion{$_}];      $discussionitems[$alldiscussion{$post}]='<tex>\vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}</tex>'.$discussionitems[$alldiscussion{$post}];
     $discussion.=$discussionitems[$alldiscussion{$_}];      $discussion.=$discussionitems[$alldiscussion{$post}];
  } elsif ($outputtarget eq 'export') {   } elsif ($outputtarget eq 'export') {
                     my $postfilename = $alldiscussion{$_}.'-'.$imsitems{$alldiscussion{$_}}{'timestamp'}.'.html';                      my $postfilename = $alldiscussion{$post}.'-'.$imsitems{$alldiscussion{$post}}{'timestamp'}.'.html';
                     if ($manifestok) {                      if ($manifestok) {
                         if (($depth[$alldiscussion{$_}] <= $currdepth) && ($alldiscussion{$_} != $firstidx)) {                          if (($depth[$alldiscussion{$post}] <= $currdepth) && ($alldiscussion{$post} != $firstidx)) {
                             print $manifestfile '  </item>'."\n";                              print $manifestfile '  </item>'."\n";
                         }                          }
                         $currdepth = $depth[$alldiscussion{$_}];                          $currdepth = $depth[$alldiscussion{$post}];
                         print $manifestfile "\n".                           print $manifestfile "\n". 
       '<item identifier="ITEM-'.$ressymb.'-'.$alldiscussion{$_}.'" isvisible="'.        '<item identifier="ITEM-'.$ressymb.'-'.$alldiscussion{$post}.'" isvisible="'.
         $imsitems{$alldiscussion{$_}}{'isvisible'}.'" identifieref="RES-'.$ressymb.'-'.$alldiscussion{$_}.'">'.          $imsitems{$alldiscussion{$post}}{'isvisible'}.'" identifieref="RES-'.$ressymb.'-'.$alldiscussion{$post}.'">'.
         '<title>'.$imsitems{$alldiscussion{$_}}{'title'}.'</title>';          '<title>'.$imsitems{$alldiscussion{$post}}{'title'}.'</title>';
                         $imsresources .= "\n".                          $imsresources .= "\n".
     '<resource identifier="RES-'.$ressymb.'-'.$alldiscussion{$_}.'" type="webcontent" href="'.$postfilename.'">'."\n".      '<resource identifier="RES-'.$ressymb.'-'.$alldiscussion{$post}.'" type="webcontent" href="'.$postfilename.'">'."\n".
       '<file href="'.$postfilename.'">'."\n".        '<file href="'.$postfilename.'">'."\n".
       $imsfiles{$alldiscussion{$_}}{$imsitems{$alldiscussion{$_}}{'currversion'}}."\n".        $imsfiles{$alldiscussion{$post}}{$imsitems{$alldiscussion{$post}}{'currversion'}}."\n".
     '</resource>';      '</resource>';
                     }                      }
                     my $postingfile;                      my $postingfile;
                     my $postingfilename = $tempexport.'/'.$postfilename;                      my $postingfilename = $tempexport.'/'.$postfilename;
                     if ($postingfile = Apache::File->new('>'.$postingfilename)) {                      if ($postingfile = Apache::File->new('>'.$postingfilename)) {
                         print $postingfile '<html><head><title>Discussion Post</title></head><body>'.                          print $postingfile '<html><head><title>Discussion Post</title></head><body>'.
                                            $imsitems{$alldiscussion{$_}}{'title'}.' '.                                             $imsitems{$alldiscussion{$post}}{'title'}.' '.
                                            $imsitems{$alldiscussion{$_}}{'sender'}.                                             $imsitems{$alldiscussion{$post}}{'sender'}.
                                            $imsitems{$alldiscussion{$_}}{'timestamp'}.'<br /><br />'.                                             $imsitems{$alldiscussion{$post}}{'timestamp'}.'<br /><br />'.
                                            $imsitems{$alldiscussion{$_}}{'message'}.'<br />'.                                             $imsitems{$alldiscussion{$post}}{'message'}.'<br />'.
                                            $imsitems{$alldiscussion{$_}}{'attach'}.'</body></html>'."\n";                                              $imsitems{$alldiscussion{$post}}{'attach'}.'</body></html>'."\n"; 
                         close($postingfile);                          close($postingfile);
                     } else {                      } else {
                         $discussion .= 'An error occurred opening the export file for posting '.$alldiscussion{$_}.'<br />';                          $discussion .= $lt{'aerr'}.' '.$alldiscussion{$post}.'<br />';
                     }                      }
                     $copyresult.=&replicate_attachments($imsitems{$alldiscussion{$_}}{'allattachments'},$tempexport);                      $copyresult.=&replicate_attachments($imsitems{$alldiscussion{$post}}{'allattachments'},$tempexport);
                 } else {                  } else {
                     $discussion.='<td  bgcolor="'.$bgcols[$newitem{$alldiscussion{$_}}].                      $discussion.='<td  bgcolor="'.$bgcols[$newitem{$alldiscussion{$post}}].
                        '" colspan="'.$colspan.'">'. $discussionitems[$alldiscussion{$_}].                         '" colspan="'.$colspan.'">'. $discussionitems[$alldiscussion{$post}].
                        '</td></tr>';                         '</td></tr>';
                 }                  }
     }      }
Line 589  END Line 603  END
                     $discussion .= &mt('Posts by').':';                      $discussion .= &mt('Posts by').':';
                     if ($totposters > 0) {                      if ($totposters > 0) {
                         foreach my $poster (@posters) {                          foreach my $poster (@posters) {
                             $poster =~ s/:/\@/;  
                             $discussion .= ' '.$poster.',';                              $discussion .= ' '.$poster.',';
                         }                          }
                         $discussion =~ s/,$//;                          $discussion =~ s/,$//;
Line 602  END Line 615  END
                         $filterchoice = '<i>'.&mt('sections').'</i>-&nbsp;'.$env{'form.sectionpick'};                          $filterchoice = '<i>'.&mt('sections').'</i>-&nbsp;'.$env{'form.sectionpick'};
                         $filterchoice .= '&nbsp;&nbsp;&nbsp; ';                          $filterchoice .= '&nbsp;&nbsp;&nbsp; ';
                     }                      }
                       if (@grouppick > 0) {
                           $filterchoice = '<i>'.&mt('groups').'</i>-&nbsp;'.$env{'form.grouppick'};
                           $filterchoice .= '&nbsp;&nbsp;&nbsp; ';
                       }
                     if (@rolefilter > 0) {                      if (@rolefilter > 0) {
                         $filterchoice .= '<i>'.&mt('roles').'</i>-';                          $filterchoice .= '<i>'.&mt('roles').'</i>-';
                         foreach (@rolefilter) {                          foreach my $role (@rolefilter) {
                             $filterchoice .= '&nbsp;'.$role_types{$_}.',';                              $filterchoice .= '&nbsp;'.$role_types{$role}.',';
                         }                          }
                         $filterchoice =~ s/,$//;                          $filterchoice =~ s/,$//;
                         $filterchoice .= '<br />&nbsp;&nbsp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp&nbsp;';                          $filterchoice .= '<br />&nbsp;&nbsp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp&nbsp;';
Line 632  END Line 649  END
               </table>                </table>
              </td>               </td>
             </tr>              </tr>
            </table>  
            <br /><br /></form>  
 END  END
               $discussion .= &action_links_bar($colspan,$ressymb,$visible,
                                                $newpostsflag,$group,
                                                $prevread,$markondisp);
               $discussion .= "
              </table>
              <br /><br /></form>\n";
         }           } 
         if ($outputtarget eq 'export') {          if ($outputtarget eq 'export') {
             if ($manifestok) {              if ($manifestok) {
Line 666  END Line 687  END
                     open(OUTPUT, "zip -r $imszip *  2> /dev/null |");                      open(OUTPUT, "zip -r $imszip *  2> /dev/null |");
                     close(OUTPUT);                      close(OUTPUT);
                     chdir $cwd;                      chdir $cwd;
                     $discussion .= 'Download the zip file from <a href="'.$imszipfile.'">Discussion Posting Archive</a><br />';                      $discussion .= &mt('Download the zip file from [_1]Discussion Posting Archive','<a href="'.$imszipfile.'">').'</a><br />';
                     if ($copyresult) {                      if ($copyresult) {
                         $discussion .= 'The following errors occurred during export - <br />'.$copyresult;                          $discussion .= &mt('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 />'.&mt('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 />';
             }              }
             return $discussion;              return $discussion;
         }          }
Line 680  END Line 701  END
     if ($discussiononly) {      if ($discussiononly) {
         my $now = time;          my $now = time;
         my $attachnum = 0;          my $attachnum = 0;
         my $newattachmsg = '';          my $currnewattach = [];
         my @currnewattach = ();          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 = &unescape($env{'form.subject'});
             $comment = &Apache::lonnet::unescape($env{'form.comment'});              $comment = &unescape($env{'form.comment'});
             my @keepold = ();              my @keepold = ();
             &process_attachments(\@currnewattach,\@currdelold,\@keepold);              &process_attachments($currnewattach,$currdelold,\@keepold);
             if (@currnewattach > 0) {              if (@{$currnewattach} > 0) {
                 $attachnum += @currnewattach;                  $attachnum += @{$currnewattach};
             }              }
         }          }
  if (&discussion_open($status)) {   if (&discussion_open($status)) {
     $discussion.=(<<ENDDISCUSS);              if (($group ne '') && ($mode eq 'board')) {  
 <form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data">                  if (&check_group_priv($group,'pgd') eq 'ok') {
 <input type="submit" name="discuss" value="Post Discussion" />                      $discussion .=
 <input type="submit" name="anondiscuss" value="Post Anonymous Discussion" />   &postingform_display($mode,$ressymb,$now,$subject,
 <input type="hidden" name="symb" value="$ressymb" />       $comment,$outputtarget,$attachnum,
 <input type="hidden" name="sendit" value="true" />       $currnewattach,$currdelold,
 <input type="hidden" name="timestamp" value="$now" />       $group);
 <br /><a name="newpost"></a>  
 <font size="1">Note: in anonymous discussion, your name is visible only   
 to course faculty</font><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>  
 ENDDISCUSS  
             if ($env{'form.origpage'}) {  
                 $discussion.='<input type="hidden" name="origpage" value="'.$env{'form.origpage'}.'" />'."\n";  
                 foreach (@currnewattach) {  
                     $discussion.='<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n";  
                 }  
             }  
             $discussion.="</form>\n";  
             if ($outputtarget ne 'tex') {  
                 $discussion.=&generate_attachments_button('',$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,'',$mode);  
                 if (@currnewattach > 0) {  
                     $newattachmsg .= '<b>New attachments</b><br />';  
                     if (@currnewattach > 1) {  
                         $newattachmsg .= '<ol>';  
                         foreach my $item (@currnewattach) {  
                             $item =~ m#.*/([^/]+)$#;  
                             $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";  
                     }  
                 }                  }
                 $discussion.=$newattachmsg;              } else {
         $discussion.=&generate_preview_button();          $discussion.= 
     }      &postingform_display($mode,$ressymb,$now,$subject,
    $comment,$outputtarget,$attachnum,
    $currnewattach,$currdelold);
               }
  }   }
     } else {      } else {
           $discussion.='<table class="LC_feedback_link"><tr><td>';
         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.= &send_feedback_link($ressymb,$target).
     $ressymb.':::" '.$target.'>'.                                '<br />';
     '<img src="'.&Apache::loncommon::lonhttpdurl('/adm/lonMisc/chat.gif').'" border="0" />'.              }
     &mt('Post Discussion').'</a></td></tr></table>';  
     }  
  }   }
           if ($outputtarget ne 'tex') {
       $discussion.= &send_message_link($ressymb);
           }
           $discussion.='</td></tr></table>';
       }
       return $discussion;
   }
   
   sub send_feedback_link {
       my ($ressymb,$target) = @_;
       my $output = '<span class="LC_feedback_link">'.
                    ' <a href="/adm/feedback?replydisc='.
                    &escape($ressymb).':::" '.$target.'>'.
                    '<img alt="" src="'.
                    &Apache::loncommon::lonhttpdurl('/adm/lonMisc/chat.gif').
                    '" border="0" />'.&mt('Post Discussion').'</a></span>';
       return $output;
   }
   
   sub send_message_link {
       my ($ressymb) = @_;
       my $output = '<span class="LC_feedback_link">'.
                    '  <a href="/adm/feedback?sendmessageonly=1&amp;symb='.
                    &escape($ressymb).'"><img alt="" src="'.
                    &Apache::loncommon::lonhttpdurl('/adm/lonMisc/feedback.gif').
                    '" border="0" />'.&mt('Send Message').'</a></span>';
       return $output;
   }
   
   sub action_links_bar {
       my ($colspan,$ressymb,$visible,$newpostsflag,$group,$prevread,$markondisp) = @_;
       my $discussion = '<tr><td bgcolor="#DDDDBB" colspan="'.$colspan.'">'.
                        '<table border="0" width="100%" bgcolor="#DDDDBB"><tr>';
       my $escsymb=&escape($ressymb);
       if ($visible>2) {
           $discussion .= '<td align="left">'.
                          '<a href="/adm/feedback?cmd=threadedon&amp;symb='.$escsymb;
           if ($newpostsflag) {
               $discussion .= '&previous='.$prevread;
           }
           $discussion .= &group_args($group);
           $discussion .='">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.
                         '<a href="/adm/feedback?cmd=threadedoff&amp;symb='.$escsymb;
           if ($newpostsflag) {
               $discussion .= '&previous='.$prevread;
           }
           $discussion .= &group_args($group);
           $discussion .='">'.&mt('Chronological View').'</a>&nbsp;&nbsp;
                          <a href= "/adm/feedback?cmd=sortfilter&amp;symb='.$escsymb;
           if ($newpostsflag) {
               $discussion .= '&previous='.$prevread;
           }
           $discussion .= &group_args($group);
           $discussion .='">'.&mt('Sorting/Filtering options').'</a>&nbsp;&nbsp';
       } else {
           $discussion .= '<td align="left">';
       }
       $discussion .='<a href= "/adm/feedback?export='.$escsymb;
       if ($newpostsflag) {
           $discussion .= '&previous='.$prevread;
       }
       $discussion .= &group_args($group);
       $discussion .= '">'.&mt('Export').'?</a>&nbsp;&nbsp;</td>';
       if ($newpostsflag) {
           if (!$markondisp) {
               $discussion .='<td align="right"><a href="/adm/preferences?action=changediscussions';
               $discussion .= &group_args($group);
               $discussion .= '">'.
                              &mt('Preferences on what is marked as NEW').
                              '</a><br /><a href="/adm/feedback?markread=1&amp;symb='.$escsymb;
               $discussion .= &group_args($group);
               $discussion .= '">'.&mt('Mark NEW posts no longer new').'</a>';
           } else {
               $discussion .= '<td>&nbsp;</td>';
           }
       } else {
           $discussion .= '<td>&nbsp;</td>';
     }      }
       $discussion .= '</tr></table></td></tr>';
     return $discussion;      return $discussion;
 }  }
   
   sub postingform_display {
       my ($mode,$ressymb,$now,$subject,$comment,$outputtarget,$attachnum,
           $currnewattach,$currdelold,$group) = @_;
       my $newattachmsg;
       my %lt = &Apache::lonlocal::texthash(
                 'note' => 'Note: in anonymous discussion, your name is visible only to course faculty',
                'title' => 'Title',
                'podi' => 'Post Discussion',
                'poan' => 'Post Anonymous Discussion',
                'newa' => 'New attachments',
       );
       my $postingform = (<<ENDDISCUSS);
   <form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data"> <input type="submit" name="discuss" value="$lt{'podi'}" />
   <input type="submit" name="anondiscuss" value="$lt{'poan'}" /> <input type="hidden" name="symb" value="$ressymb" />
   <input type="hidden" name="sendit" value="true" />
   <input type="hidden" name="timestamp" value="$now" />
   <br /><a name="newpost"></a>
   <font size="1">$lt{'note'}</font><br />
   <b>$lt{'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>
   ENDDISCUSS
       if ($env{'form.origpage'}) {
           $postingform .= '<input type="hidden" name="origpage" value="'.
                           $env{'form.origpage'}.'" />'."\n";
           foreach my $att (@{$currnewattach}) {
               $postingform .= '<input type="hidden" name="currnewattach" '.
                               'value="'.$att.'" />'."\n";
           }
       }
       if (exists($env{'form.ref'})) {
           $postingform .= '<input type="hidden" name="ref" value="'.
                           $env{'form.ref'}.'" />';
       }
       if ($group ne '') {
           $postingform .='<input type="hidden" name="group" value="'.$group.'" />';
       }
       my $blockblog = &Apache::loncommon::blocking_status('blogs');
       if (!$blockblog) {
           $postingform .= &add_blog_checkbox();
       }
       $postingform .= "</form>\n";
       if ($outputtarget ne 'tex') {
           $postingform .= &generate_attachments_button('',$attachnum,$ressymb,
                                                        $now,$currnewattach,
                                                        $currdelold,'',$mode,
                                                        $blockblog);
           if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) {
               $newattachmsg = '<br /><b>'.$lt{'newa'}.'</b><br />';
               if (@{$currnewattach} > 1) {
                   $newattachmsg .= '<ol>';
                   foreach my $item (@{$currnewattach}) {
                       $item =~ m#.*/([^/]+)$#;
                       $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";
               }
           }
           $postingform .= $newattachmsg;
           $postingform .= &generate_preview_button();
       }
       return $postingform;
   }
   
 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,$grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,$anonhash,$anoncnt,$group) = @_;
     my @original=();      my @original=();
     my @index=();      my @index=();
       my $skip_group_check = 0;
     my $symb=&Apache::lonenc::check_decrypt($ressymb);      my $symb=&Apache::lonenc::check_decrypt($ressymb);
       my $escsymb=&escape($ressymb);
     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'});
   
       if ((@{$grouppick} == 0) || (grep(/^all$/,@{$grouppick}))) {
           $skip_group_check = 1;
       }
     if ($contrib{'version'}) {      if ($contrib{'version'}) {
         my $oldest = $contrib{'1:timestamp'};          my $oldest = $contrib{'1:timestamp'};
         if ($prevread eq '0') {          if ($prevread eq '0') {
Line 768  sub build_posting_display { Line 911  sub build_posting_display {
         }          }
         my ($skiptest,$rolematch,$roleregexp,$secregexp,$statusregexp);          my ($skiptest,$rolematch,$roleregexp,$secregexp,$statusregexp);
         if ($sortposts) {          if ($sortposts) {
             ($skiptest,$roleregexp,$secregexp,$statusregexp) = &filter_regexp($rolefilter,$sectionpick,$statusfilter);              ($skiptest,$roleregexp,$secregexp,$statusregexp) = 
                        &filter_regexp($rolefilter,$sectionpick,$statusfilter);
             $rolematch = $roleregexp.':'.$secregexp.':'.$statusregexp;              $rolematch = $roleregexp.':'.$secregexp.':'.$statusregexp;
         }           } 
  for (my $id=1;$id<=$contrib{'version'};$id++) {   for (my $id=1;$id<=$contrib{'version'};$id++) {
Line 807  sub build_posting_display { Line 951  sub build_posting_display {
  $$visible++;   $$visible++;
                 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'});
                         $numoldver = @oldversions;                          $numoldver = @oldversions;
                     } else {                      } else {
                         $numoldver = 1;                          $numoldver = 1;
Line 820  sub build_posting_display { Line 964  sub build_posting_display {
                 my %allattachments = ();                  my %allattachments = ();
                 my ($screenname,$plainname);                  my ($screenname,$plainname);
                 my $sender = &mt('Anonymous');                  my $sender = &mt('Anonymous');
   # Anonymous users getting number within a discussion
   # Since idx is in static order, this should give the same sequence every time. 
    my $key=$contrib{$idx.':sendername'}.'@'.$contrib{$idx.':senderdomain'};
    unless ($$anonhash{$key}) {
                       $anoncnt++;
       $$anonhash{$key}=&mt('Anonymous').' '.$anoncnt;
    }
                 my ($message,$subject,$vgrlink,$ctlink);                  my ($message,$subject,$vgrlink,$ctlink);
                 &get_post_contents(\%contrib,$idx,$seeid,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,$numoldver);                  &get_post_contents(\%contrib,$idx,$seeid,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,$numoldver);
   
Line 839  sub build_posting_display { Line 990  sub build_posting_display {
   
                         if ($subject eq '') {                          if ($subject eq '') {
                            if (defined($$subjectsort{'__No subject'})) {                             if (defined($$subjectsort{'__No subject'})) {
                                push @{$$subjectsort{'__No subject'}}, $idx;                                 push(@{$$subjectsort{'__No subject'}}, $idx);
                            } else {                             } else {
                                @{$$subjectsort{'__No subject'}} = ("$idx");                                 @{$$subjectsort{'__No subject'}} = ("$idx");
                            }                             }
                         } else {                          } else {
                             if (defined($$subjectsort{$subject})) {                              if (defined($$subjectsort{$subject})) {
                                push @{$$subjectsort{$subject}}, $idx;                                 push(@{$$subjectsort{$subject}}, $idx);
                             } else {                              } else {
                                @{$$subjectsort{$subject}} = ("$idx");                                 @{$$subjectsort{$subject}} = ("$idx");
                             }                              }
                         }                          }
         if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {          if ((!$contrib{$idx.':anonymous'}) || (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) {
     $sender=&Apache::loncommon::aboutmewrapper(      $sender=&Apache::loncommon::aboutmewrapper(
  $plainname,   $plainname,
  $contrib{$idx.':sendername'},   $contrib{$idx.':sendername'},
Line 858  sub build_posting_display { Line 1009  sub build_posting_display {
  $contrib{$idx.':sendername'}.' at '.   $contrib{$idx.':sendername'}.' at '.
  $contrib{$idx.':senderdomain'}.')';   $contrib{$idx.':senderdomain'}.')';
     if ($contrib{$idx.':anonymous'}) {      if ($contrib{$idx.':anonymous'}) {
         $sender.=' <font color="red"><b>['.&mt('anonymous').']</b></font> '.          $sender.=' <font color="red"><b>['.$$anonhash{$key}.']</b></font> '.
     $screenname;      $screenname;
     }      }
   
Line 867  sub build_posting_display { Line 1018  sub build_posting_display {
                                 %{$$usernamesort{$contrib{$idx.':senderdomain'}}} = ();                                  %{$$usernamesort{$contrib{$idx.':senderdomain'}}} = ();
                             }                              }
                             if (defined($$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}})) {                              if (defined($$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}})) {
                                 push @{$$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}}, $idx;                                  push(@{$$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}}, $idx);
                             } else {                              } else {
                                 @{$$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}} = ("$idx");                                  @{$$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}} = ("$idx");
                             }                              }
Line 887  sub build_posting_display { Line 1038  sub build_posting_display {
                                 %{$$namesort{$lastname}} = ();                                  %{$$namesort{$lastname}} = ();
                             }                              }
                             if (defined($$namesort{$lastname}{$firstname})) {                              if (defined($$namesort{$lastname}{$firstname})) {
                                 push @{$$namesort{$lastname}{$firstname}}, $idx;                                  push(@{$$namesort{$lastname}{$firstname}}, $idx);
                             } 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 (&editing_allowed($escsymb.':::'.$idx,$group)) {
                                 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;                                           $escsymb.':::'.$idx;
                                     if ($newpostsflag) {                                      if ($$newpostsflag) {
                                         $sender .= '&previous='.$prevread;                                          $sender .= '&previous='.$prevread;
                                     }                                      }
                                     $sender .= '" '.$target.'>'.&mt('Edit').'</a>';                                                   $sender .= &group_args($group);
                                       $sender .= '" '.$target.'>'.&mt('Edit').'</a>';
                                       
                                     unless ($seeid) {                                      unless ($seeid) {
                                         $sender.=" <a href=\"javascript:studentdelete('$ressymb','$idx','$newpostsflag','$prevread')";                                          my $grpargs = &group_args($group);
                                           $sender.=" <a href=\"javascript:verifydelete('studentdelete','$escsymb','$idx','$$newpostsflag','$prevread','$grpargs')";
                                         $sender .= '">'.&mt('Delete').'</a>';                                          $sender .= '">'.&mt('Delete').'</a>';
                                     }                                      }
                                 }                                  }
Line 909  sub build_posting_display { Line 1063  sub build_posting_display {
         if ($hidden) {          if ($hidden) {
                                     unless ($studenthidden) {                                      unless ($studenthidden) {
                 $sender.=' <a href="/adm/feedback?unhide='.                  $sender.=' <a href="/adm/feedback?unhide='.
                 $ressymb.':::'.$idx;                  $escsymb.':::'.$idx;
                                         if ($newpostsflag) {                                          if ($$newpostsflag) {
                                              $sender .= '&previous='.$prevread;                                              $sender .= '&previous='.$prevread;
                                         }                                          }
                                         $sender .= '">'.&mt('Make Visible').'</a>';                                          $sender .= '">'.&mt('Make Visible').'</a>';
                                     }                                      }
         } else {          } else {
     $sender.=' <a href="/adm/feedback?hide='.      $sender.=' <a href="/adm/feedback?hide='.
         $ressymb.':::'.$idx;          $escsymb.':::'.$idx;
                                     if ($newpostsflag) {                                      if ($$newpostsflag) {
                                         $sender .= '&previous='.$prevread;                                          $sender .= '&previous='.$prevread;
                                     }                                      }
       $sender .= &group_args($group);
                                     $sender .= '">'.&mt('Hide').'</a>';                                      $sender .= '">'.&mt('Hide').'</a>';
         }                               }
         $sender.=' <a href="/adm/feedback?deldisc='.                                  my $grpargs = &group_args($group);
         $ressymb.':::'.$idx;          $sender.= 
                                 if ($newpostsflag) {                                      " <a href=\"javascript:verifydelete('seeiddelete','$escsymb','$idx','$$newpostsflag','$prevread','$grpargs')\">";
                                     $sender .= '&previous='.$prevread;                                  $sender .= &mt('Delete').'</a>';
                                 }  
                                 $sender .= '">'.&mt('Delete').'</a>';  
                             }                              }
         } else {          } else {
     if ($screenname) {      if ($screenname) {
         $sender='<i>'.$screenname.'</i>';          $sender='<i>'.$screenname.'</i>';
       } else {
    $sender='<i>'.$$anonhash{$key}.'</i>';
     }      }
 # Set up for sorting by domain, then username for anonymous  # Set up for sorting by domain, then username for anonymous
                             unless (defined($$usernamesort{'__anon'})) {                              unless (defined($$usernamesort{'__anon'})) {
                                 %{$$usernamesort{'__anon'}} = ();                                  %{$$usernamesort{'__anon'}} = ();
                             }                              }
                             if (defined($$usernamesort{'__anon'}{'__anon'})) {                              if (defined($$usernamesort{'__anon'}{'__anon'})) {
                                 push @{$$usernamesort{'__anon'}{'__anon'}}, $idx;                                  push(@{$$usernamesort{'__anon'}{'__anon'}}, $idx);
                             } else {                              } else {
                                 @{$$usernamesort{'__anon'}{'__anon'}} = ("$idx");                                  @{$$usernamesort{'__anon'}{'__anon'}} = ("$idx");
                             }                              }
Line 948  sub build_posting_display { Line 1103  sub build_posting_display {
                                 %{$$namesort{'__anon'}} = ();                                  %{$$namesort{'__anon'}} = ();
                             }                              }
                             if (defined($$namesort{'__anon'}{'__anon'})) {                              if (defined($$namesort{'__anon'}{'__anon'})) {
                                 push @{$$namesort{'__anon'}{'__anon'}}, $idx;                                  push(@{$$namesort{'__anon'}{'__anon'}}, $idx);
                             } else {                              } else {
                                 @{$$namesort{'__anon'}{'__anon'}} = ("$idx");                                  @{$$namesort{'__anon'}{'__anon'}} = ("$idx");
                             }                              }
         }          }
         if (&discussion_open($status) &&          if (&discussion_open($status)) {
         &Apache::lonnet::allowed('pch',                              if (($group ne '') && 
  $env{'request.course.id'}.                                  (&check_group_priv($group,'pgd') eq 'ok')) {
  ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {                                   $sender.=' <a href="/adm/feedback?replydisc='.
     $sender.=' <a href="/adm/feedback?replydisc='.                                            $escsymb.':::'.$idx;
             $ressymb.':::'.$idx;                                  if ($$newpostsflag) {
                             if ($newpostsflag) {                                      $sender .= '&previous='.$prevread;
                                   }
                                   $sender .= &group_args($group);
                                   $sender .= '" '.$target.'>'.&mt('Reply').'</a>';
                               } elsif (&Apache::lonnet::allowed('pch', 
    $env{'request.course.id'}.
    ($env{'request.course.sec'}?'/'.
                                     $env{'request.course.sec'}:''))) {
            $sender.=' <a href="/adm/feedback?replydisc='.
                     $escsymb.':::'.$idx;
                                   if ($$newpostsflag) {
                                     $sender .= '&previous='.$prevread;                                      $sender .= '&previous='.$prevread;
                                   }
                                   $sender .= '" '.$target.'>'.&mt('Reply').'</a>';
                             }                              }
                             $sender .= '" '.$target.'>'.&mt('Reply').'</a>';  
                         }                          }
         if ($viewgrades) {          if ($viewgrades) {
         $vgrlink=&Apache::loncommon::submlink('Submissions',          $vgrlink=&Apache::loncommon::submlink('Submissions',
Line 1019  sub build_posting_display { Line 1185  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;
                             if (defined($env{'form.totposters'})) {                              if ($env{'form.totposters'} ne '') {
                                 if ($totposters == 0) {                                  if ($totposters == 0) {
                                     $$shown{$idx} = 0;                                      $$shown{$idx} = 0;
                                 } elsif ($totposters > 0) {                                  } elsif ($totposters > 0) {
Line 1044  sub build_posting_display { Line 1210  sub build_posting_display {
                                         }                                          }
                                     }                                      }
                                 }                                  }
                                   if ($$shown{$idx} && !$skip_group_check) {
                                       my $showflag = 0;
                                       if (ref($$classgroups{$poster}{active}) eq 'HASH') {
                                           foreach my $grp (@{$grouppick}) {
                                               if (grep/^\Q$grp\E$/,
                                    keys(%{$$classgroups{$poster}{active}})) {
                                                   $showflag = 1;
                                                   last;
                                               }
                                           }
                                       }
                                       if ($showflag) {
                                           $$shown{$idx} = 1;
                                       } else {
                                           $$shown{$idx} = 0;
                                       }
                                   }
                             } else {                              } else {
                                 $$shown{$idx} = 1;                                  $$shown{$idx} = 1;
                             }                              }
Line 1074  sub build_posting_display { Line 1257  sub build_posting_display {
                                 my @postversions = ();                                  my @postversions = ();
                                 $$discussionitems[$idx] .= &mt('This post has been edited by the author.');                                  $$discussionitems[$idx] .= &mt('This post has been edited by the author.');
                                 if ($seeid) {                                  if ($seeid) {
                                     $$discussionitems[$idx] .= '&nbsp;&nbsp;<a href="/adm/feedback?allversions='.$ressymb.':::'.$idx.'">'.&mt('Display all versions').'</a>';                                      $$discussionitems[$idx] .= '&nbsp;&nbsp;<a href="/adm/feedback?allversions='.$escsymb.':::'.$idx;
       $$discussionitems[$idx] .= &group_args($group);
                                       $$discussionitems[$idx] .= '">'.&mt('Display all versions').'</a>';
                                 }                                  }
                                 $$discussionitems[$idx].='<br/>'.&mt('Earlier version(s) were posted on: ');                                  $$discussionitems[$idx].='<br/>'.&mt('Earlier version(s) were posted on: ');
                                 if ($contrib{$idx.':history'} =~ m/:/) {                                  if ($contrib{$idx.':history'} =~ m/:/) {
                                     @postversions = split/:/,$contrib{$idx.':history'};                                      @postversions = split(/:/,$contrib{$idx.':history'});
                                 } else {                                  } else {
                                     @postversions = ("$contrib{$idx.':history'}");                                      @postversions = ("$contrib{$idx.':history'}");
                                 }                                  }
Line 1101  sub filter_regexp { Line 1286  sub filter_regexp {
     my $skiptest = 1;      my $skiptest = 1;
     if (@{$rolefilter} > 0) {      if (@{$rolefilter} > 0) {
         my @okrolefilter = ();          my @okrolefilter = ();
         foreach (@{$rolefilter}) {          foreach my $role (@{$rolefilter}) {
             unless ($_ eq '') {              unless ($role eq '') {
                 push @okrolefilter, $_;                  push(@okrolefilter, $role);
             }              }
         }          }
         if (@okrolefilter > 0) {          if (@okrolefilter > 0) {
Line 1121  sub filter_regexp { Line 1306  sub filter_regexp {
     }      }
     if (@{$sectionpick} > 0) {      if (@{$sectionpick} > 0) {
         my @oksectionpick = ();          my @oksectionpick = ();
         foreach (@{$sectionpick}) {          foreach my $sec (@{$sectionpick}) {
             unless ($_ eq '') {              unless ($sec eq '') {
                  push @oksectionpick, $_;                   push(@oksectionpick, $sec);
             }              }
         }          }
         if ((@oksectionpick > 0) && (!grep/^all$/,@oksectionpick)) {          if ((@oksectionpick > 0) && (!grep/^all$/,@oksectionpick)) {
Line 1137  sub filter_regexp { Line 1322  sub filter_regexp {
             $secregexp .= '[^:]*';              $secregexp .= '[^:]*';
         }          }
     }      }
   
     if (defined($statusfilter) && $statusfilter ne '') {      if (defined($statusfilter) && $statusfilter ne '') {
         if ($statusfilter eq 'all') {          if ($statusfilter eq 'all') {
             $statusregexp = '[^:]+';              $statusregexp = '[^:]+';
Line 1157  sub get_post_contents { Line 1343  sub get_post_contents {
     %{$$imsfiles{$idx}}=();      %{$$imsfiles{$idx}}=();
     if ($type eq 'allversions') {      if ($type eq 'allversions') {
        unless($seeid) {         unless($seeid) {
            $discussion=&mt('You do not have privileges to view all versions of posts.').&mt('Please select a different role');             $discussion=&mt('You do not have privileges to view all versions of posts.').' '.&mt('Please select a different role.');
            return $discussion;             return $discussion;
        }          } 
     }      }
 #    $$screenname=&Apache::loncommon::screenname(  #    $$screenname=&Apache::loncommon::screenname(
 #                                        $$contrib{$idx.':sendername'},  #                                        $$contrib{$idx.':sendername'},
 #                                        $$contrib{$idx.':senderdomain'});  #                                        $$contrib{$idx.':senderdomain'});
 #    $$plainname=&Apache::loncommon::nickname(      $$plainname=&Apache::loncommon::nickname(
 #                                        $$contrib{$idx.':sendername'},                                          $$contrib{$idx.':sendername'},
 #                                        $$contrib{$idx.':senderdomain'});                                          $$contrib{$idx.':senderdomain'});
     ($$screenname,$$plainname)=($$contrib{$idx.':screenname'},      $$screenname=$$contrib{$idx.':screenname'};
  $$contrib{$idx.':plainname'});  
     my $sender=&Apache::loncommon::aboutmewrapper(      my $sender=&Apache::loncommon::aboutmewrapper(
                                  $$plainname,                                   $$plainname,
                                  $$contrib{$idx.':sendername'},                                   $$contrib{$idx.':sendername'},
Line 1180  sub get_post_contents { Line 1366  sub get_post_contents {
     if ($type eq 'allversions' || $type eq 'export') {      if ($type eq 'allversions' || $type eq 'export') {
         $start = 0;          $start = 0;
         if ($$contrib{$idx.':history'}) {          if ($$contrib{$idx.':history'}) {
             if ($$contrib{$idx.':history'} =~ m/:/) {      @postversions = split(/:/,$$contrib{$idx.':history'});
                 @postversions = split/:/,$$contrib{$idx.':history'};  
             } else {  
                 @postversions = ("$$contrib{$idx.':history'}");  
             }  
         }          }
         &get_post_versions($messages,$$contrib{$idx.':message'},1);          &get_post_versions($messages,$$contrib{$idx.':message'},1);
         &get_post_versions($subjects,$$contrib{$idx.':subject'},1);          &get_post_versions($subjects,$$contrib{$idx.':subject'},1);
         push @postversions,$$contrib{$idx.':timestamp'};          push(@postversions,$$contrib{$idx.':timestamp'});
         $end = @postversions;          $end = @postversions;
     } else {      } else {
         &get_post_versions($messages,$$contrib{$idx.':message'},1,$numver);          &get_post_versions($messages,$$contrib{$idx.':message'},1,$numver);
Line 1215  sub get_post_contents { Line 1397  sub get_post_contents {
         if ($type eq 'export') {          if ($type eq 'export') {
             $$imsfiles{$idx}{$i} = '';              $$imsfiles{$idx}{$i} = '';
             if ($attachmsg) {              if ($attachmsg) {
                 $$attachtxt{$i} = '<br />Attachments:<br />';                  $$attachtxt{$i} = '<br />'.&mt('Attachments').':<br />';
                 foreach (sort keys %currattach) {                  foreach my $key (sort(keys(%currattach))) {
                     if ($$allattachments{$_}{'filename'} =~ m-^/uploaded/([^/]+/[^/]+)(/feedback)?(/?\d*)/([^/]+)$-) {                      if ($$allattachments{$key}{'filename'} =~ m-^/uploaded/([^/]+/[^/]+)(/feedback)?(/?\d*)/([^/]+)$-) {
                         my $fname = $1.$3.'/'.$4;                          my $fname = $1.$3.'/'.$4;
                         $$imsfiles{$idx}{$i} .= '<file href="'.$fname.'">'."\n";                          $$imsfiles{$idx}{$i} .= '<file href="'.$fname.'">'."\n";
                         $$attachtxt{$i}.= '<a href="'.$fname.'">'.$4.'</a><br />';                          $$attachtxt{$i}.= '<a href="'.$fname.'">'.$4.'</a><br />';
Line 1226  sub get_post_contents { Line 1408  sub get_post_contents {
             }              }
         } else {          } else {
             if ($attachmsg) {              if ($attachmsg) {
                 $$attachtxt{$i} = '<br />Attachments:'.$attachmsg.'<br />';                  $$attachtxt{$i} = '<br />'.&mt('Attachments').':'.$attachmsg.'<br />';
             } else {              } else {
                 $$attachtxt{$i} = '';                  $$attachtxt{$i} = '';
             }              }
Line 1240  END Line 1422  END
         }          }
     }      }
     if ($type eq 'allversions') {      if ($type eq 'allversions') {
         $discussion.=('</ul></body></html>');          $discussion.='</ul>';
         return $discussion;          return $discussion;
     } else {      } else {
         return;          return;
Line 1250  END Line 1432  END
 sub replicate_attachments {  sub replicate_attachments {
     my ($attachrefs,$tempexport) = @_;      my ($attachrefs,$tempexport) = @_;
     my $response;      my $response;
     foreach my $id (keys %{$attachrefs}) {      foreach my $id (keys(%{$attachrefs})) {
         if ($$attachrefs{$id}{'filename'} =~ m-^/uploaded/([^/]+)/([^/]+)(/feedback)?(/?\d*)/([^/]+)$-) {          if ($$attachrefs{$id}{'filename'} =~ m-^/uploaded/([^/]+)/([^/]+)(/feedback)?(/?\d*)/([^/]+)$-) {
             my $path = $tempexport;              my $path = $tempexport;
             my $tail = $1.'/'.$2.$4;              my $tail = $1.'/'.$2.$4;
             my @extras = split/\//,$tail;              my @extras = split(/\//,$tail);
             my $destination = $tempexport.'/'.$1.'/'.$2.$4.'/'.$5;              my $destination = $tempexport.'/'.$1.'/'.$2.$4.'/'.$5;
             if (!-e $destination) {              if (!-e $destination) {
                 my $i= 0;                  my $i= 0;
Line 1273  sub replicate_attachments { Line 1455  sub replicate_attachments {
                         print $attachcopy $content;                          print $attachcopy $content;
                         close($attachcopy);                          close($attachcopy);
                     } else {                      } else {
                         $response .= 'Error copying file attachment - '.$5.' to IMS package: '.$!.'<br />'."\n";                          $response .= &mt('Error copying file attachment - [_1] to IMS package',$5).': '.$!.'<br />'."\n";
                     }                      }
                 } else {                  } else {
                     &Apache::lonnet::logthis("Replication of attachment failed when building IMS export of discussion posts - domain: $1, course: $2, file: $$attachrefs{$id}{'filename'} -error: $rtncode");                      &Apache::lonnet::logthis("Replication of attachment failed when building IMS export of discussion posts - domain: $1, course: $2, file: $$attachrefs{$id}{'filename'} -error: $rtncode");
                     $response .= 'Error copying file attachment - '.$5.' to IMS package: '.$rtncode.'<br />'."\n";                      $response .= &mt('Error copying file attachment - [_1] to IMS package: ',$5).$rtncode.'<br />'."\n";
                 }                  }
             }              }
         }          }
Line 1286  sub replicate_attachments { Line 1468  sub replicate_attachments {
 }  }
   
 sub mail_screen {  sub mail_screen {
   my ($r,$feedurl,$options) = @_;    my ($r,$feedurl,$options,$caller_symb) = @_;
   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','blog','group','ref']);
   }    }
   my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion',  
                                           '','onLoad="window.focus();setposttype();"');    my %lt = &Apache::lonlocal::texthash(
   my $title=&Apache::lonnet::gettitle($feedurl);              'plch' => 'Please check at least one of the following feedback types:',
   if (!$title) { $title = $feedurl; }              'myqu' => 'My question/comment/feedback:',
               'title' => 'Title',
               'reta' => 'Retained attachments',
               'atta' => 'Attachment (128 KB max size)',
              );
     my $restitle = &get_resource_title($caller_symb,$feedurl);
   my $quote='';    my $quote='';
   my $subject = '';    my $subject = '';
   my $comment = '';    my $comment = '';
Line 1311  sub mail_screen { Line 1498  sub mail_screen {
   my $attachnum = 0;    my $attachnum = 0;
   my $anonchk = (<<END);    my $anonchk = (<<END);
   function anonchk() {    function anonchk() {
      if (document.mailform.anondiscuss.checked == true) {        for (var i=0; i < document.mailform.discuss.length; i++) {
           document.attachment.anondiscuss.value = '1'    if (document.mailform.discuss[i].checked) {
      }        document.attachment.discuss.value = 
      if (document.mailform.discuss.checked == true) {    document.mailform.discuss[i].value;
           document.attachment.discuss.value = '1'    }
      }        }
         if (document.mailform.blog.checked) {
     document.attachment.blog.value = 1;
         }
      return       return
    }     }
 END  END
Line 1324  END Line 1514  END
   if (exists($env{'form.origpage'})) {    if (exists($env{'form.origpage'})) {
       $anonscript = (<<END);        $anonscript = (<<END);
   function setposttype() {    function setposttype() {
       var anondisc = $env{'form.anondiscuss'};        var disc = "$env{'form.discuss'}";
       var disc = $env{'form.discuss'};        for (var i=0; i < document.mailform.discuss.length; i++) {
       if (anondisc == 1) {    if (disc == document.mailform.discuss[i].value) {
           document.mailform.anondiscuss.checked = true        document.mailform.discuss[i].checked = 1;
     }
       }        }
       if (disc == 1) {        var blog = "$env{'form.blog'}";
           document.mailform.discuss.checked = true        if (blog == 1) {
             document.mailform.blog.checked=1;
       }        }
       return        return
   }    }
Line 1354  END Line 1546  END
       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'} =~ /:/) {
                   my @oldversions = split/:/,$contrib{$idx.':history'};                    my @oldversions = split(/:/,$contrib{$idx.':history'});
                   $numoldver = @oldversions;                    $numoldver = @oldversions;
               } else {                } else {
                   $numoldver = 1;                    $numoldver = 1;
Line 1363  END Line 1555  END
           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'});
                       $numoldver = @oldversions;                        $numoldver = @oldversions;
                   } else {                    } else {
                       $numoldver = 1;                        $numoldver = 1;
                   }                    }
               }                }
               my $message;  
               if ($idx > 0) {                if ($idx > 0) {
                   my %msgversions = ();                    my %msgversions = ();
                   &get_post_versions(\%msgversions,$contrib{$idx.':message'},0,$numoldver);                    &get_post_versions(\%msgversions,$contrib{$idx.':message'},0,$numoldver);
                   $message = $msgversions{$numoldver};                    $quote = $msgversions{$numoldver};
               }                }
       &newline_to_br(\$message);  
       $quote='<blockquote>'.&Apache::lontexconvert::msgtexconverted($message).'</blockquote>';  
               if ($idx > 0) {                if ($idx > 0) {
                   my %subversions = ();                    my %subversions = ();
                   &get_post_versions(\%subversions,$contrib{$idx.':subject'},1,$numoldver);                    &get_post_versions(\%subversions,$contrib{$idx.':subject'},1,$numoldver);
                   $subject = 'Re: '.$subversions{$numoldver};                    $subject = &mt('Re: ').$subversions{$numoldver};
               }                }
               $subject = &HTML::Entities::encode($subject,'<>&"');                $subject = &HTML::Entities::encode($subject,'<>&"');
           } else {            } else {
Line 1397  END Line 1586  END
                   $parentmsg = $contrib{$idx.':replyto'};                    $parentmsg = $contrib{$idx.':replyto'};
               }                }
               unless (exists($env{'form.origpage'})) {                unless (exists($env{'form.origpage'})) {
                   my $anonflag = 0;                    my $anonflag = 'nonanon';
                   if ($contrib{$idx.':anonymous'}) {                    if ($contrib{$idx.':anonymous'}) {
                       $anonflag = 1;                        $anonflag = 'anon';
                   }                    }
                   $anonscript = (<<END);                    $anonscript = (<<END);
   function setposttype () {    function setposttype () {
       var currtype = $anonflag        var currtype = "$anonflag";
       if (currtype == 1) {        for (var i=0; i<document.mailform.discuss.length; i++) {
           document.mailform.elements.discuss.checked = false    if (document.mailform.elements.discuss[i].value == currtype ) {
           document.mailform.elements.anondiscuss.checked = true        document.mailform.elements.discuss[i].checked=1;
       }    } 
       if (currtype == 0) {  
           document.mailform.elements.anondiscuss.checked = false  
           document.mailform.elements.discuss.checked = true  
       }        }
       return        return
   }    }
Line 1424  END Line 1610  END
   }    }
   
   if ($env{'form.origpage'}) {    if ($env{'form.origpage'}) {
       $subject = &Apache::lonnet::unescape($env{'form.subject'});        $subject = &unescape($env{'form.subject'});
       $comment = &Apache::lonnet::unescape($env{'form.comment'});        $comment = &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 $send=&mt('Send');    my $send=&mt('Send');
   my $html=&Apache::lonxml::xmlbegin();    my $alert = &mt('Please select a feedback type.');
   $r->print(<<END);    my $js= <<END;
 $html  
 <head>  
 <title>The LearningOnline Network with CAPA</title>  
 <meta http-equiv="pragma" content="no-cache"></meta>  
 $htmlheader  
 <script type="text/javascript">  <script type="text/javascript">
 //<!--  //<!--
     function gosubmit() {      function gosubmit() {
         var rec=0;          var rec=0;
         if (typeof(document.mailform.elements.author)!="undefined") {  
           if (document.mailform.elements.author.checked) {  
              rec=1;  
           }   
         }  
         if (typeof(document.mailform.elements.question)!="undefined") {  
           if (document.mailform.elements.question.checked) {  
              rec=1;  
           }   
         }  
         if (typeof(document.mailform.elements.course)!="undefined") {  
           if (document.mailform.elements.course.checked) {  
              rec=1;  
           }   
         }  
         if (typeof(document.mailform.elements.policy)!="undefined") {  
           if (document.mailform.elements.policy.checked) {  
              rec=1;  
           }   
         }  
         if (typeof(document.mailform.elements.discuss)!="undefined") {          if (typeof(document.mailform.elements.discuss)!="undefined") {
           if (document.mailform.elements.discuss.checked) {      if (typeof(document.mailform.elements.discuss.length) == "undefined") {
              rec=1;   if (document.mailform.elements.discuss.checked ) {
           }       rec=1;
         }   }
         if (typeof(document.mailform.elements.anondiscuss)!="undefined") {      } else {
           if (document.mailform.elements.anondiscuss.checked) {   for (var i=0; i<document.mailform.elements.discuss.length; i++) {
       if (document.mailform.elements.discuss[i].checked ) {
    rec=1;
       } 
    }
       }
    }
           if (typeof(document.mailform.elements.blog)!="undefined") {
             if (document.mailform.elements.blog.checked) {
              rec=1;               rec=1;
           }             } 
         }          }
Line 1479  $htmlheader Line 1647  $htmlheader
     }      }
     document.mailform.submit();      document.mailform.submit();
         } else {          } else {
             alert('Please check a feedback type.');              alert('$alert');
  }   }
     }      }
     $anonchk      $anonchk
     $anonscript      $anonscript
 //-->  //-->
 </script>  </script>
 </head>  END
 $bodytag  
 <h2><tt>$title</tt></h2>    my %onload = ('onload' => 'window.focus();setposttype();');
     my $start_page=
         &Apache::loncommon::start_page('Resource Feedback and Discussion',$js,
        {'add_entries' => \%onload});
   
     if ($quote ne '') {
         &newline_to_br(\$quote);
         $quote='<blockquote>'.&Apache::lontexconvert::msgtexconverted($quote).'</blockquote>';
     }
   
     $r->print(<<END);
   $start_page
   <h2><tt>$restitle</tt></h2>
 <form action="/adm/feedback" method="post" name="mailform"  <form action="/adm/feedback" method="post" name="mailform"
 enctype="multipart/form-data">  enctype="multipart/form-data">
 $prevtag  $prevtag
Line 1505  END Line 1685  END
 END  END
   }    }
   $r->print(<<END);    $r->print(<<END);
 Please check at least one of the following feedback types:  $lt{'plch'}
 $options<hr />  $options<hr />
 $quote  $quote
 <p>My question/comment/feedback:</p>  <p>$lt{'myqu'}</p>
 <p>  <p>
 $latexHelp  $latexHelp
 Title: <input type="text" name="subject" size="30" value="$subject" /></p>  $lt{'title'}: <input type="text" name="subject" size="30" value="$subject" /></p>
 <p>  <p>
 <textarea name="comment" id="comment" cols="60" rows="10" wrap="hard">$comment  <textarea name="comment" id="comment" cols="60" rows="10" wrap="hard">$comment
 </textarea></p>  </textarea></p>
Line 1519  Title: <input type="text" name="subject" Line 1699  Title: <input type="text" name="subject"
 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 my $attach (@currnewattach) {
                 $r->print('<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n");                  $r->print('<input type="hidden" name="currnewattach" value="'.$attach.'" />'."\n");
             }              }
             foreach (@currdelold) {              foreach my $oldatt (@currdelold) {
                 $r->print('<input type="hidden" name="deloldattach" value="'.$_.'" />'."\n");                  $r->print('<input type="hidden" name="deloldattach" value="'.$oldatt.'" />'."\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));
                 foreach (keys %currattach) {                  foreach my $key (keys(%currattach)) {
                     $r->print('<input type="hidden" name="keepold" value="'.$_.'" />'."\n");                      $r->print('<input type="hidden" name="keepold" value="'.$key.'" />'."\n");
                 }                  }
             }              }
         }          }
     } else {      } else {
         $r->print(<<END);          $r->print(<<END);
 Attachment (128 KB max size): <input type="file" name="attachment" />  $lt{'atta'}: <input type="file" name="attachment" />
 </p>  </p>
 END  END
     }      }
       if (exists($env{'form.group'})) {
           $r->print('<input type="hidden" name="group" value="'.$env{'form.group'}.'" />');
       }
       if (exists($env{'form.ref'})) {
           $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.'" />');
       }
     $r->print(<<END);      $r->print(<<END);
 <p>  <p>
 <input type="hidden" name="sendit" value="1" />  <input type="hidden" name="sendit" value="1" />
Line 1551  END Line 1737  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;
           &Apache::lonenc::check_encrypt(\$ressymb);
         my $postidx = '';          my $postidx = '';
         if ($env{'form.editdisc'}) {          if ($env{'form.editdisc'}) {
             $postidx = $idx;              $postidx = $idx;
Line 1558  END Line 1745  END
         if (@currnewattach > 0) {          if (@currnewattach > 0) {
             $attachnum += @currnewattach;              $attachnum += @currnewattach;
         }          }
         $r->print(&generate_attachments_button($postidx,$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,$numoldver));          my $blockblog = &Apache::loncommon::blocking_status('blogs');
           $r->print(&generate_attachments_button($postidx,$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,$numoldver,'',$blockblog));
         if ($attachnum > 0) {          if ($attachnum > 0) {
             if (@currnewattach > 0) {              if (@currnewattach > 0) {
                 $newattachmsg .= '<b>New attachments</b><br />';                  $newattachmsg .= '<br /><b>'.&mt('New attachments').'</b><br />';
                 if (@currnewattach > 1) {                  if (@currnewattach > 1) {
                     $newattachmsg .= '<ol>';                      $newattachmsg .= '<ol>';
                     foreach my $item (@currnewattach) {                      foreach my $item (@currnewattach) {
Line 1575  END Line 1763  END
                 }                  }
             }              }
             if ($attachmsg) {              if ($attachmsg) {
                 $r->print("<b>Retained attachments</b>:$attachmsg<br />\n");                  $r->print("<br /><b>$lt{'reta'}</b>:$attachmsg<br />\n");
             }              }
             if ($newattachmsg) {              if ($newattachmsg) {
                 $r->print("$newattachmsg<br />");                  $r->print("$newattachmsg<br />");
Line 1584  END Line 1772  END
     }      }
     $r->print(&generate_preview_button().      $r->print(&generate_preview_button().
               &Apache::lonhtmlcommon::htmlareaselectactive('comment').                &Apache::lonhtmlcommon::htmlareaselectactive('comment').
               '</body></html>');        &Apache::loncommon::end_page());
   
 }  }
   
 sub print_display_options {  sub print_display_options {
Line 1595  sub print_display_options { Line 1784  sub print_display_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 %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'dido' => 'Discussion display options',  
         'pref' => 'Display Preference',          'pref' => 'Display Preference',
         'curr' => 'Current setting ',          'curr' => 'Current setting ',
         'actn' => 'Action',          'actn' => 'Action',
Line 1657  sub print_display_options { Line 1843  sub print_display_options {
         $currtogg = $lt{'toggon'};          $currtogg = $lt{'toggon'};
         $disctogg = 'toggon';          $disctogg = 'toggon';
     }      }
     my $html=&Apache::lonxml::xmlbegin();  
     $r->print(<<END);      my $js = <<END;
 $html  <script type="text/javascript">
 <head>  
 <title>$lt{'dido'}</title>  
 <meta http-equiv="pragma" content="no-cache" />  
 <script>  
 function discdispChk(caller) {  function discdispChk(caller) {
     var disctogg = '$toggchg'      var disctogg = '$toggchg'
     if (caller == 0) {      if (caller == 0) {
Line 1730  function setDisp() { Line 1912  function setDisp() {
     }      }
 }  }
 </script>  </script>
 </head>  END
 $bodytag  
 <form name="modifydisp" method="post" action="/adm/feedback">  
       my $start_page =
    &Apache::loncommon::start_page('Discussion display options',$js);
       my $end_page =
    &Apache::loncommon::end_page();
       $r->print(<<END);
   $start_page
   <form name="modifydisp" method="POST" action="/adm/feedback">
 $lt{'sdpf'}<br/> $lt{'prca'}  <ol><li>$lt{'whpo'}</li><li>$lt{'unwh'}</li><li>$lt{'wipa'}</li></ol>  $lt{'sdpf'}<br/> $lt{'prca'}  <ol><li>$lt{'whpo'}</li><li>$lt{'unwh'}</li><li>$lt{'wipa'}</li></ol>
 <br />  <br />
 <table border="0" cellpadding="0" cellspacing="0">  END
  <tr>      $r->print(&Apache::loncommon::start_data_table());
   <td width="100%" bgcolor="#000000">      $r->print(<<END);
    <table width="100%" border="0" cellpadding="1" cellspacing="0">         <tr>
     <tr>          <th>$lt{'pref'}</td>
      <td width="100%" bgcolor="#000000">          <th>$lt{'curr'}</td>
       <table border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">          <th>$lt{'actn'}?</td>
        <tr bgcolor="$tabcolor">  
         <td><b>$lt{'pref'}</b></td>  
         <td><b>$lt{'curr'}</b></td>  
         <td><b>$lt{'actn'}?</b></td>  
        </tr>         </tr>
        <tr bgcolor="#dddddd">  END
       $r->print(&Apache::loncommon::start_data_table_row());
       $r->print(<<END);
        <td>$lt{'disa'}</td>         <td>$lt{'disa'}</td>
        <td>$lt{$discdisp}</td>         <td>$lt{$discdisp}</td>
        <td><label><input type="checkbox" name="discdisp" onClick="discdispChk('0')" />&nbsp;$lt{'chgt'} "$dispchangeA"</label>         <td><label><input type="checkbox" name="discdisp" onClick="discdispChk('0')" />&nbsp;$lt{'chgt'} "$dispchangeA"</label>
            <br />             <br />
            <label><input type="checkbox" name="discdisp" onClick="discdispChk('1')" />&nbsp;$lt{'chgt'} "$dispchangeB"</label>             <label><input type="checkbox" name="discdisp" onClick="discdispChk('1')" />&nbsp;$lt{'chgt'} "$dispchangeB"</label>
        </td>         </td>
       </tr><tr bgcolor="#eeeeee">  END
       $r->print(&Apache::loncommon::end_data_table_row());
       $r->print(&Apache::loncommon::start_data_table_row());
       $r->print(<<END);
        <td>$lt{'npmr'}</td>         <td>$lt{'npmr'}</td>
        <td>$lt{$discmark}</td>         <td>$lt{$discmark}</td>
        <td><label><input type="checkbox" name="discmark" />$lt{'chgt'} "$markchange"</label></td>         <td><label><input type="checkbox" name="discmark" />$lt{'chgt'} "$markchange"</label></td>
       </tr><tr bgcolor="#dddddd">  END
       $r->print(&Apache::loncommon::end_data_table_row());
       $r->print(&Apache::loncommon::start_data_table_row());
       $r->print(<<END);
        <td>$lt{'dotm'}</td>         <td>$lt{'dotm'}</td>
        <td>$lt{$disctogg}</td>         <td>$lt{$disctogg}</td>
        <td><label><input type="checkbox" name="disctogg" onClick="discdispChk('2')" />$lt{'chgt'} "$toggchange"</label></td>         <td><label><input type="checkbox" name="disctogg" onClick="discdispChk('2')" />$lt{'chgt'} "$toggchange"</label></td>
       </tr>  END
      </table>      $r->print(&Apache::loncommon::end_data_table_row());
     </td>      $r->print(&Apache::loncommon::end_data_table());
    </tr>      $r->print(<<END);
   </table>  
  </td>  
 </tr>  
 </table>  
 <br />  <br />
 <br />  <br />
 <input type="hidden" name="symb" value="$symb" />  <input type="hidden" name="symb" value="$symb" />
Line 1779  $lt{'sdpf'}<br/> $lt{'prca'}  <ol><li>$l Line 1968  $lt{'sdpf'}<br/> $lt{'prca'}  <ol><li>$l
 <input type="hidden" name="$markchg" value=""/>  <input type="hidden" name="$markchg" value=""/>
 <input type="hidden" name="$toggchg" value="" />  <input type="hidden" name="$toggchg" value="" />
 <input type="button" name="sub" value="Store Changes" onClick="javascript:setDisp()" />  <input type="button" name="sub" value="Store Changes" onClick="javascript:setDisp()" />
   END
       if (exists($env{'form.group'})) {
           $r->print('<input type="hidden" name="group" value="'.$env{'form.group'}.'" />');
       }
       if (exists($env{'form.ref'})) {
           $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.'" />');
       }
       $r->print("
 <br />  <br />
 <br />  <br />
 </form>  </form>
 </body>  $end_page
 </html>      ");
 END  
     return;      return;
 }  }
   
Line 1795  sub print_sortfilter_options { Line 1991  sub print_sortfilter_options {
     $r->send_http_header;      $r->send_http_header;
   
     &Apache::lonenc::check_encrypt(\$symb);      &Apache::lonenc::check_encrypt(\$symb);
     my @sections = ();      my @sections;
     my $section_sel = '';      my $section_sel = '';
     my $numsections = 0;  
     my $numvisible = 5;      my $numvisible = 5;
     my %sectioncount = ();      my @groups;
       my $group_sel = '';
     $numsections = &Apache::loncommon::get_sections($env{'course.'.$env{'request.course.id'}.'.domain'},$env{'course.'.$env{'request.course.id'}.'.num'},\%sectioncount);      my $numgroupvis = 5;
       my %sectioncount = &Apache::loncommon::get_sections();
   
     if ($env{'request.course.sec'} !~ /^\s*$/) {  #Restrict section choice to current section       if ($env{'request.course.sec'} !~ /^\s*$/) {  #Restrict section choice to current section 
         @sections = ('all',$env{'request.course.sec'});          @sections = ('all',$env{'request.course.sec'});
         $numvisible = 2;          $numvisible = 2;
     } else {      } else {
         @sections = sort {$a cmp $b} keys(%sectioncount);          @sections = sort {$a cmp $b} keys(%sectioncount);
           if (scalar(@sections) < 4) {
               $numvisible = scalar(@sections) + 1;
           }
         unshift(@sections,'all'); # Put 'all' at the front of the list          unshift(@sections,'all'); # Put 'all' at the front of the list
         if ($numsections < 4) {  
             $numvisible = $numsections + 1;      }
       foreach my $sec (@sections) {
           $section_sel .= "  <option value=\"$sec\">$sec</option>\n";
       }
   
       if (&check_group_priv() eq 'ok') {
           my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
           my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; 
           my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum);
           @groups = sort {$a cmp $b} keys(%curr_groups);
           if (scalar(@groups) < 4) {
               $numgroupvis = scalar(@groups) + 1;
           }
           unshift(@groups,'all'); # Put 'all' at the front of the list
       } else { 
           my @coursegroups = split(/:/,$env{'request.course.groups'});
           if (@coursegroups > 0) {
               @coursegroups = sort {$a cmp $b} @coursegroups;
               @groups = ('all',@coursegroups);
               if (scalar(@groups) < 4) {
                   $numgroupvis = scalar(@groups) + 1;
               }
           } else {
               @groups = ('all');
               $numgroupvis = 1;
         }          }
     }      }
     foreach (@sections) {      foreach my $group (@groups) {
         $section_sel .= "  <option value=\"$_\" />$_\n";          $group_sel .= "  <option value=\"$group\">$group</option>\n";
     }      }
                                                                                      
     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 %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         'diso' => 'Discussion sorting and filtering options',  
         'diop' => 'Display Options',          'diop' => 'Display Options',
         'curr' => 'Current setting ',          'curr' => 'Current setting ',
         'actn' => 'Action',          'actn' => 'Action',
Line 1832  sub print_sortfilter_options { Line 2052  sub print_sortfilter_options {
         'spur' => 'Specific user roles',          'spur' => 'Specific user roles',
         'sprs' => 'Specific role status',          'sprs' => 'Specific role status',
         'spse' => 'Specific sections',          'spse' => 'Specific sections',
           'spgr' => 'Specific groups',
         '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',
           'stor' => 'Store changes',
     );      );
   
     my %sort_types = ();      my %sort_types = ();
     my %role_types = ();      my %role_types = ();
     my %status_types = ();      my %status_types = ();
     &sort_filter_names(\%sort_types,\%role_types,\%status_types);      &sort_filter_names(\%sort_types,\%role_types,\%status_types);
     my $html=&Apache::lonxml::xmlbegin();  
     $r->print(<<END);      my $js = <<END;
 $html  
 <head>  
 <title>$lt{'diso'}</title>  
 <meta http-equiv="pragma" content="no-cache" />  
 <script type="text/javascript">  <script type="text/javascript">
 function verifyFilter() {  function verifyFilter() {
     var rolenum = 0      var rolenum = 0
Line 1867  function verifyFilter() { Line 2085  function verifyFilter() {
     if (secnum == 0) {      if (secnum == 0) {
         document.modifyshown.sectionpick.options[0].selected = true          document.modifyshown.sectionpick.options[0].selected = true
     }      }
   
       var grpnum = 0
       for (var i=0; i<document.modifyshown.grouppick.length; i++) {
           if (document.modifyshown.grouppick.options[i].selected == true) {
               grpnum ++
           }
       }
       if (grpnum == 0) {
           document.modifyshown.grouppick.options[0].selected = true
       }
   
     document.modifyshown.submit();      document.modifyshown.submit();
 }  }
 </script>  </script>
 </head>  END
 $bodytag  
 <form name="modifyshown" method="post" action="/adm/feedback">      my $start_page=
    &Apache::loncommon::start_page('Discussion options',$js);
       my $end_page=
    &Apache::loncommon::end_page();
   
       $r->print(<<END);
   $start_page
   <form name="modifyshown" method="POST" action="/adm/feedback">
 <b>$lt{'diso'}</b><br/> $lt{'prca'}  <b>$lt{'diso'}</b><br/> $lt{'prca'}
 <br /><br />  <br /><br />
 <table border="0">  <table border="0">
Line 1885  $bodytag Line 2121  $bodytag
   <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{'spgr'}</b></td>
     <td>&nbsp;</td>
   <td><b>$lt{'psub'}</b></td>    <td><b>$lt{'psub'}</b></td>
  </tr>   </tr>
  <tr>   <tr>
   <td align="center">    <td align="center" valign="top">
    <select name="sortposts">     <select name="sortposts">
     <option value="ascdate" selected="selected" />$sort_types{'ascdate'}      <option value="ascdate" selected="selected">$sort_types{'ascdate'}</option>
     <option value="descdate" />$sort_types{'descdate'}      <option value="descdate">$sort_types{'descdate'}</option>
     <option value="thread" />$sort_types{'thread'}      <option value="thread">$sort_types{'thread'}</option>
     <option value="subject" />$sort_types{'subject'}      <option value="subject">$sort_types{'subject'}</option>
     <option value="username" />$sort_types{'username'}      <option value="username">$sort_types{'username'}</option>
     <option value="lastfirst" />$sort_types{'lastfirst'}      <option value="lastfirst">$sort_types{'lastfirst'}</option>
    </select>     </select>
   </td>    </td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td align="center">    <td align="center" valign="top">
    <select name="statusfilter">     <select name="statusfilter">
     <option value="all" selected="selected" />$status_types{'all'}      <option value="all" selected="selected">$status_types{'all'}</option>
     <option value="Active" />$status_types{'Active'}      <option value="Active">$status_types{'Active'}</option>
     <option value="Expired" />$status_types{'Expired'}      <option value="Expired">$status_types{'Expired'}</option>
       <option value="Future">$status_types{'Future'}</option>
    </select>     </select>
   </td>    </td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td align="center">    <td align="center" valign="top">
    <select name="rolefilter" multiple="true" size="5">     <select name="rolefilter" multiple="true" size="5">
     <option value="all" />$role_types{'all'}      <option value="all">$role_types{'all'}</option>
     <option value="st" />$role_types{'st'}      <option value="st">$role_types{'st'}</option>
     <option value="cc" />$role_types{'cc'}      <option value="cc">$role_types{'cc'}</option>
     <option value="in" />$role_types{'in'}      <option value="in">$role_types{'in'}</option>
     <option value="ta" />$role_types{'ta'}      <option value="ta">$role_types{'ta'}</option>
     <option value="ep" />$role_types{'ep'}      <option value="ep">$role_types{'ep'}</option>
     <option value="ad" />$role_types{'ad'}      <option value="cr">$role_types{'cr'}</option>
     <option value="cr" />$role_types{'cr'}  
    </select>     </select>
   </td>    </td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
   <td align="center">    <td align="center" valign="top">
    <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><label><input type="checkbox" name="posterlist" value="$symb" />$lt{'shal'}</label></td>    <td align="center" valign="top">
      <select name="grouppick" multiple="true" size="$numvisible">
       $group_sel
      </select>
     </td>
     <td>&nbsp;</td>
     <td valign="top"><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="verifyFilter()" />  <input type="button" name="sub" value="$lt{'stor'}" onClick="verifyFilter()" />
   END
       if (exists($env{'form.group'})) {
           $r->print('<input type="hidden" name="group" value="'.$env{'form.group'}.'" />');
       }
       if (exists($env{'form.ref'})) {
           $r->print('<input type="hidden" name="ref" value="'.$env{'form.ref'}.'" />');
       }
       $r->print("
 <br />  <br />
 <br />  <br />
 </form>  </form>
 </body>  $end_page
 </html>  ");
 END  
 }  }
   
 sub print_showposters {  sub print_showposters {
Line 1954  sub print_showposters { Line 2205  sub print_showposters {
         $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;
       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       my $group = $env{'form.group'};
       my $ressymb = &wrap_symb($symb);
       if (($group ne '') &&
           ($ressymb =~ m|^bulletin___ \d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|)) {
           if (&check_group_priv($group,'dgp') eq 'ok') {
               $seeid = 1;
           }
       } else {
           $seeid=&Apache::lonnet::allowed('rin',$crs);
       }
     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'},                                           $cdom,$cnum);
                           $env{'course.'.$env{'request.course.id'}.'.num'});  
     my %namesort = ();      my %namesort = ();
     my %postcounts = ();      my %postcounts = ();
     my %lt=&Apache::lonlocal::texthash(  
                      'diso' => 'Discussion filtering options',      my %lt = &Apache::lonlocal::texthash(
     );                                            sele => 'Select',
     my $bodytag=&Apache::loncommon::bodytag('Discussion options',                                            full => 'Fullname',
                                           '','');                                            usdo => 'Username:domain',
                                             post => 'Posts',
                                           );
     if ($contrib{'version'}) {      if ($contrib{'version'}) {
         for (my $idx=1;$idx<=$contrib{'version'};$idx++) {          for (my $idx=1;$idx<=$contrib{'version'};$idx++) {
             my $hidden=($contrib{'hidden'}=~/\.$idx\./);              my $hidden=($contrib{'hidden'}=~/\.$idx\./);
             my $deleted=($contrib{'deleted'}=~/\.$idx\./);              my $deleted=($contrib{'deleted'}=~/\.$idx\./);
             unless ((($hidden) && (!$seeid)) || ($deleted)) {              unless ((($hidden) && (!$seeid)) || ($deleted)) {
                 if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {                  if ((!$contrib{$idx.':anonymous'}) || (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) {
                     my %names = &Apache::lonnet::get('environment',['firstname','lastname'],$contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'});                      my %names = &Apache::lonnet::get('environment',['firstname','lastname'],$contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'});
                     my $lastname = $names{'lastname'};                      my $lastname = $names{'lastname'};
                     my $firstname = $names{'firstname'};                      my $firstname = $names{'firstname'};
Line 1987  sub print_showposters { Line 2251  sub print_showposters {
                     $postcounts{$poster} ++;                      $postcounts{$poster} ++;
                     if (defined($namesort{$lastname}{$firstname})) {                      if (defined($namesort{$lastname}{$firstname})) {
                         if (!grep/^$poster$/,@{$namesort{$lastname}{$firstname}}) {                          if (!grep/^$poster$/,@{$namesort{$lastname}{$firstname}}) {
                             push @{$namesort{$lastname}{$firstname}}, $poster;                              push(@{$namesort{$lastname}{$firstname}}, $poster);
                         }                          }
                     } else {                      } else {
                         @{$namesort{$lastname}{$firstname}} = ("$poster");                          @{$namesort{$lastname}{$firstname}} = ("$poster");
Line 1996  sub print_showposters { Line 2260  sub print_showposters {
             }              }
         }          }
     }      }
     my $html=&Apache::lonxml::xmlbegin();  
       my $start_page = &Apache::loncommon::start_page('Discussion options');
       my $table_start =&Apache::loncommon::start_data_table();
     $r->print(<<END);      $r->print(<<END);
 $html  $start_page
 <head>  
 <title>$lt{'diso'}</title>  
 <meta http-equiv="pragma" content="no-cache" />  
 </head>  
 $bodytag  
  <form name="pickpostersform" method="post">   <form name="pickpostersform" method="post">
   <table border="0">   <br />
    <tr>      $table_start
     <td bgcolor="#777777">        <tr>
      <table border="0" cellpadding="3">         <th>#</th>
       <tr bgcolor="#e6ffff">         <th>$lt{'sele'}</th>
        <td><b>No.</b></td>         <th>$lt{'full'} <font color="#999999">($lt{'usdo'})</font></th>
        <td><b>Select</b></td>         <th>$lt{'post'}</th>
        <td><b>Fullname</b><font color="#999999">(Username/domain)</font></td>  
        <td><b>Posts</td>  
       </tr>        </tr>
 END  END
     my $count = 0;      my $count = 0;
     foreach my $last (sort keys %namesort) {      foreach my $last (sort(keys(%namesort))) {
         foreach my $first (sort keys %{$namesort{$last}}) {          foreach my $first (sort(keys(%{$namesort{$last}}))) {
             foreach (sort @{$namesort{$last}{$first}}) {              foreach my $user (sort(@{$namesort{$last}{$first}})) {
                 my ($uname,$udom) = split/:/,$_;                  my ($uname,$udom) = split(/:/,$user);
                 if (!$uname || !$udom) {                   if (!$uname || !$udom) { 
                     next;                      next;
                 } else {                  } else {
                     $count ++;                      $count ++;
                     $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>');                      $r->print(&Apache::loncommon::start_data_table_row().
         '<td align="right">'.$count.'</td>
                                  <td align="center"><label><input name="stuinfo" type="checkbox" value="'.$user.'" /></td>
                                  <td>'.$last.', '.$first.' ('.$uname.':'.$udom.')</label></td>
                                  <td>'.$postcounts{$user}.'</td>'.
         &Apache::loncommon::end_data_table_row());
                 }                  }
             }              }
         }          }
     }      }
       $r->print(&Apache::loncommon::end_data_table());
       my $end_page   = &Apache::loncommon::end_page();
     $r->print(<<END);      $r->print(<<END);
      </table>  
     </td>  
    </tr>  
   </table>  
 <br />  <br />
 <input type="hidden" name="sortposts" value="$sortposts" />  <input type="hidden" name="sortposts" value="$sortposts" />
 <input type="hidden" name="userpick" value="$symb" />  <input type="hidden" name="userpick" value="$symb" />
 <input type="button" name="store" value="Display posts" onClick="javascript:document.pickpostersform.submit()" />  <input type="button" name="store" value="Display posts" onClick="javascript:document.pickpostersform.submit()" />
 </form>  </form>
 </body>  $end_page
 </html>  
 END  END
 }  }
   
Line 2049  sub get_post_versions { Line 2310  sub get_post_versions {
     my ($versions,$incoming,$htmldecode,$numver) = @_;      my ($versions,$incoming,$htmldecode,$numver) = @_;
     if ($incoming =~ /^<version num="0">/) {      if ($incoming =~ /^<version num="0">/) {
         my $p = HTML::LCParser->new(\$incoming);          my $p = HTML::LCParser->new(\$incoming);
         my $done = 0;                                                                                 my $done = 0; 
   
         while ( (my $token = $p->get_tag("version")) && (!$done)) {          while ( (my $token = $p->get_tag("version")) && (!$done)) {
             my $num = $token->[1]{num};              my $num = $token->[1]{num};
             my $text = $p->get_text("/version");              my $text = $p->get_text("/version");
Line 2109  sub get_post_attachments { Line 2371  sub get_post_attachments {
 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 %lt = &Apache::lonlocal::texthash(
                    'sorr' => 'Sorry, no recipients  ...',
     );
   my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');    my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
   my $html=&Apache::lonxml::xmlbegin();    $r->print(&Apache::loncommon::start_page('Feedback not sent',undef,
   $r->print (<<ENDFAILREDIR);     {'redirect'  => [2,$feedurl],
 $html      'only_body' => 1,}));
 <head>    $r->print(<<ENDFAILREDIR);
 <title>Feedback not sent</title>  
 <meta http-equiv="pragma" content="no-cache" />  
 <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />  
 </head>  
 <body bgcolor="#FFFFFF">  
 <img align="right" src="$logo" />  <img align="right" src="$logo" />
 <b>Sorry, no recipients  ...</b>  <b>$lt{'sorr'}</b>
 <br /><a href="$feedurl">Continue</a>  
 </body>  
 </html>  
 ENDFAILREDIR  ENDFAILREDIR
     $r->print(&Apache::loncommon::end_page());
 }  }
   
 sub redirect_back {  sub redirect_back {
   my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous,$sort,$rolefilter,$statusfilter,$sectionpick,$numpicks) = @_;    my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$blog,$status,$previous,$sort,$rolefilter,$statusfilter,$sectionpick,$grouppick,$numpicks,$group) = @_;
   my $sorttag = '';    my $sorttag = '';
   my $roletag = '';    my $roletag = '';
   my $statustag = '';    my $statustag = '';
   my $sectag = '';    my $sectag = '';
     my $grptag = '';
   my $userpicktag = '';    my $userpicktag = '';
   my $qrystr = '';    my $qrystr = '';
   my $prevtag = '';    my $prevtag = '';
   
   &Apache::loncommon::content_type($r,'text/html');    &Apache::loncommon::content_type($r,'text/html');
   $r->send_http_header;    $r->send_http_header;
   
   &dewrapper(\$feedurl);    &dewrapper(\$feedurl);
   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };    if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
   if ($previous > 0) {    if ($previous > 0) {
Line 2167  sub redirect_back { Line 2425  sub redirect_back {
           if (ref($sectionpick) eq 'ARRAY') {            if (ref($sectionpick) eq 'ARRAY') {
               $feedurl .= '&sectionpick=';                $feedurl .= '&sectionpick=';
               $sectag .=  '<input type="hidden" name="sectionpick" value="';                $sectag .=  '<input type="hidden" name="sectionpick" value="';
               foreach (@{$sectionpick}) {                foreach my $sec (@{$sectionpick}) {
                   $feedurl .= $_.',';                    $feedurl .= $sec.',';
                   $sectag .= $_.',';                    $sectag .= $sec.',';
               }                }
               $feedurl =~ s/,$//;                $feedurl =~ s/,$//;
               $sectag =~ s/,$//;                $sectag =~ s/,$//;
Line 2178  sub redirect_back { Line 2436  sub redirect_back {
               $feedurl .= '&sectionpick='.$sectionpick;                $feedurl .= '&sectionpick='.$sectionpick;
               $sectag = '<input type="hidden" name="sectionpick" value="'.$sectionpick.'" />';                $sectag = '<input type="hidden" name="sectionpick" value="'.$sectionpick.'" />';
           }            }
             if (ref($grouppick) eq 'ARRAY') {
                 $feedurl .= '&grouppick=';
                 $sectag .=  '<input type="hidden" name="grouppick" value="';
                 foreach my $grp (@{$grouppick}) {
                     $feedurl .= $grp.',';
                     $grptag .= $grp.',';
                 }
                 $feedurl =~ s/,$//;
                 $grptag =~ s/,$//;
                 $grptag .= '" />';
             } else {
                 $feedurl .= '&grouppick='.$grouppick;
                 $grptag = '<input type="hidden" name="grouppick" value="'.$grouppick.'" />';
             }
           if (ref($rolefilter) eq 'ARRAY') {            if (ref($rolefilter) eq 'ARRAY') {
               $feedurl .= '&rolefilter=';                $feedurl .= '&rolefilter=';
               $roletag .=  '<input type="hidden" name="rolefilter" value="';                $roletag .=  '<input type="hidden" name="rolefilter" value="';
               foreach (@{$rolefilter}) {                foreach my $role (@{$rolefilter}) {
                   $feedurl .= $_.',';                    $feedurl .= $role.',';
                   $roletag .= $_.',';                    $roletag .= $role.',';
               }                }
               $feedurl =~ s/,$//;                $feedurl =~ s/,$//;
               $roletag =~ s/,$//;                $roletag =~ s/,$//;
Line 2196  sub redirect_back { Line 2468  sub redirect_back {
           $statustag ='<input type="hidden" name="statusfilter" value="'.$statusfilter.'" />';            $statustag ='<input type="hidden" name="statusfilter" value="'.$statusfilter.'" />';
       }        }
   }    }
   $feedurl=&Apache::lonenc::check_encrypt($feedurl);    my $grouptag;
     if ($group ne '') {
         $grouptag = '<input type="hidden" name="group" value="'.$group.'" />';      my $refarg;
         if (exists($env{'form.ref'})) {
             $refarg = '&amp;ref='.$env{'form.ref'};
             $grouptag .= '<input type="hidden" name="ref" value="'.$env{'form.ref'}.'" />';
         }
         if ($feedurl =~ /\?/) {
             $feedurl .= '&amp;group='.$group.$refarg;
         } else {
             $feedurl .= '?group='.$group.$refarg;
         }
     } 
     &Apache::lonenc::check_encrypt(\$feedurl);
   my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');    my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
   my $html=&Apache::lonxml::xmlbegin();    my %onload;
   $r->print (<<ENDREDIR);    if ($env{'environment.remote'} ne 'off') {
 $html        $onload{'onload'} =
 <head>    "if (window.name!='loncapaclient') { this.document.reldt.submit(); self.window.close(); }";
 <title>Feedback sent</title>    }
 <meta http-equiv="pragma" content="no-cache" />    my $start_page=
 <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />        &Apache::loncommon::start_page('Feedback sent',undef,
 </head>       {'redirect'    => [0,$feedurl],
 <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>        'only_body'   => 1,
         'add_entries' => \%onload});
     my $end_page = &Apache::loncommon::end_page();
     $r->print(<<ENDREDIR);
   $start_page
 <img align="right" src="$logo" />  <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>
   $blog
 <font color="red">$status</font>  <font color="red">$status</font>
 <form name="reldt" action="$feedurl" target="loncapaclient">  <form name="reldt" action="$feedurl" target="loncapaclient">
 $prevtag  $prevtag
Line 2217  $sorttag Line 2507  $sorttag
 $statustag  $statustag
 $roletag  $roletag
 $sectag  $sectag
   $grptag
 $userpicktag  $userpicktag
   $grouptag
 </form>  </form>
 <br /><a href="$feedurl">Continue</a>  $end_page
 </body>  
 </html>  
 ENDREDIR  ENDREDIR
 }  }
   
 sub no_redirect_back {  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 $html=&Apache::lonxml::xmlbegin();    my %onload;
   $r->print (<<ENDNOREDIR);    if ($env{'environment.remote'} ne 'off') {
 $html        $onload{'onload'} = 
 <head>    "if (window.name!='loncapaclient') { self.window.close(); }";
 <title>Feedback not sent</title>    }
 <meta http-equiv="pragma" content="no-cache" />  
 ENDNOREDIR    my %body_options = ('only_body'   => 1,
         'bgcolor'     => '#FFFFFF',
   if ($feedurl!~/^\/adm\/feedback/) {         'add_entries' => \%onload,);
       $r->print('<meta HTTP-EQUIV="Refresh" CONTENT="2; url='.  
  &Apache::lonenc::check_encrypt($feedurl).'">');    if ($feedurl !~ m{^/adm/feedback}) { 
   }        $body_options{'rediect'} = [2,$feedurl];
   $feedurl=&Apache::lonenc::check_encrypt($feedurl);    }
     my $start_page=
         &Apache::loncommon::start_page('Feedback not sent',undef,
        \%body_options);
         
     my $end_page = &Apache::loncommon::end_page();
   
     &Apache::lonenc::check_encrypt(\$feedurl);
   my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');    my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
   $r->print (<<ENDNOREDIRTWO);    $r->print (<<ENDNOREDIRTWO);
 </head>  $start_page
 <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { self.close(); }'>  
 <img align="right" src="$logo" />  <img align="right" src="$logo" />
 <b>$nofeed</b>  <b>$nofeed</b>
 <br /><a href="$feedurl">$continue</a>  <br />
 </body>  $end_page
 </html>  
 ENDNOREDIRTWO  ENDNOREDIRTWO
 }  }
   
Line 2261  sub screen_header { Line 2556  sub screen_header {
     unless (($env{'form.replydisc'}) || ($env{'form.editdisc'})) {      unless (($env{'form.replydisc'}) || ($env{'form.editdisc'})) {
  if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/) && ($env{'user.adv'})) {   if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/) && ($env{'user.adv'})) {
     $msgoptions=       $msgoptions= 
  '<p><label><input type="checkbox" name="author" /> '.   '<p><label><input type="radio" name="discuss" value="author" /> '.
  &mt('Feedback to resource author').'</label></p>';   &mt('Feedback to resource author').'</label></p>';
  }   }
  if (&feedback_available(1)) {   if (&feedback_available(1)) {
     $msgoptions.=      $msgoptions.=
  '<p><label><input type="checkbox" name="question" /> '.   '<p><label><input type="radio" name="discuss" value="question" /> '.
  &mt('Question about resource content').'</label></p>';   &mt('Question about resource content').'</label></p>';
  }   }
  if (&feedback_available(0,1)) {   if (&feedback_available(0,1)) {
     $msgoptions.=      $msgoptions.=
  '<p><label><input type="checkbox" name="course" /> '.   '<p><label><input type="radio" name="discuss" value="course" /> '.
  &mt('Question/Comment/Feedback about course content').   &mt('Question/Comment/Feedback about course content').
  '</label></p>';   '</label></p>';
  }   }
  if (&feedback_available(0,0,1)) {   if (&feedback_available(0,0,1)) {
     $msgoptions.=      $msgoptions.=
  '<p><label><input type="checkbox" name="policy" /> '.   '<p><label><input type="radio" name="discuss" value="policy" /> '.
  &mt('Question/Comment/Feedback about course policy').   &mt('Question/Comment/Feedback about course policy').
  '</label></p>';   '</label></p>';
  }   }
     }      }
     if ($env{'request.course.id'}) {      if (($env{'request.course.id'}) && (!$env{'form.sendmessageonly'})) {
  if (&discussion_open(undef,$symb) &&          my ($blocked,$blocktext) = &Apache::loncommon::blocking_status('boards');
           if (!$blocked && &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='<label><input type="checkbox" name="discuss" onClick="this.form.anondiscuss.checked=false;" '.      $discussoptions='<label><input type="radio" name="discuss" value="nonanon" checked="checked" /> '.
  ($env{'form.replydisc'}?' checked="1"':'').' /> '.  
  &mt('Contribution to course discussion of resource');   &mt('Contribution to course discussion of resource');
     $discussoptions.='</label><br /><label><input type="checkbox" name="anondiscuss" onClick="this.form.discuss.checked=false;" /> '.          $discussoptions.='</label><br /><label><input type="radio" name="discuss" value="anon" /> '.
  &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></label>';   ' <i>('.&mt('name only visible to course faculty').')</i></label> '.
    '<a href="/adm/preferences?action=changescreenname">'.&mt('Change Screenname').'</a>';
               my $blockblog = &Apache::loncommon::blocking_status('blogs');
               if (!$blockblog) {
                   $discussoptions.= &add_blog_checkbox();
               }
         }          }
     }      }
     if ($msgoptions) { $msgoptions='<h2><img src="'.&Apache::loncommon::lonhttpdurl('/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; }
Line 2315  sub resource_output { Line 2615  sub resource_output {
 }  }
   
 sub clear_out_html {  sub clear_out_html {
   my ($message,$override)=@_;    my ($message,$override,$ignore_htmlarea)=@_;
   unless (&Apache::lonhtmlcommon::htmlareablocked()) { return $message; }    if (!$ignore_htmlarea
         && !&Apache::lonhtmlcommon::htmlareablocked()) { return $message; }
 # 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
Line 2340  sub clear_out_html { Line 2641  sub clear_out_html {
 }  }
   
 sub assemble_email {  sub assemble_email {
   my ($feedurl,$message,$prevattempts,$usersaw,$useranswer)=@_;    my ($message,$prevattempts,$usersaw,$useranswer)=@_;
     my %lt = &Apache::lonlocal::texthash(
                'prev' => 'Previous attempts of student (if applicable)',
                'orig' => 'Original screen output (if applicable)',
                'corr' => 'Correct Answer(s) (if applicable)',
     );
   my $email=<<"ENDEMAIL";    my $email=<<"ENDEMAIL";
 $message  $message
 ENDEMAIL  ENDEMAIL
     my $citations=<<"ENDCITE";      my $citations=<<"ENDCITE";
 <h2>Previous attempts of student (if applicable)</h2>  <h2>$lt{'prev'}</h2>
 $prevattempts  $prevattempts
 <br /><hr />  <br /><hr />
 <h2>Original screen output (if applicable)</h2>  <h2>$lt{'orig'}</h2>
 $usersaw  $usersaw
 <h2>Correct Answer(s) (if applicable)</h2>  <h2>$lt{'corr'}</h2>
 $useranswer  $useranswer
 ENDCITE  ENDCITE
   return ($email,$citations);    return ($email,$citations);
 }  }
   
 sub secapply {  
     my $rec=shift;  
     my $defaultflag=shift;  
     $rec=~s/\s+//g;  
     $rec=~s/\@/\:/g;  
     my ($adr,$sections)=($rec=~/^([^\(]+)\(([^\)]+)\)/);  
     if ($sections) {  
  foreach (split(/\;/,$sections)) {  
             if (($_ eq $env{'request.course.sec'}) ||  
                 ($defaultflag && ($_ eq '*'))) {  
                 return $adr;   
             }  
         }  
     } else {  
        return $rec;  
     }  
     return '';  
 }  
   
 =pod   
   
 =over 4  
   
 =item *  
   
 decide_receiver($feedurl,$author,$question,$course,$policy,$defaultflag);  
   
 Arguments  
   $feedurl - /res/ url of resource (only need if $author is true)  
   $author,$question,$course,$policy - all true/false parameters  
     if true will attempt to find the addresses of user that should receive  
     this type of feedback (author - feedback to author of resource $feedurl,  
     $question 'Resource Content Questions', $course 'Course Content Question',  
     $policy 'Course Policy')  
     (Additionally it also checks $env for whether the corresponding form.<name>  
     element exists, for ease of use in a html response context)  
      
   $defaultflag - (internal should be left blank) if true gather addresses   
                  that aren't for a section even if I have a section  
                  (used for reccursion internally, first we look for  
                  addresses for our specific section then we recurse  
                  and look for non section addresses)  
   
 Returns  
   $typestyle - string of html text, describing what addresses were found  
   %to - a hash, which keys are addresses of users to send messages to  
         the keys will look like   name:domain  
   
 =cut  
   
 sub decide_receiver {  
   my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;  
   my $typestyle='';  
   my %to=();  
   if ($env{'form.author'}||$author) {  
     $typestyle.='Submitting as Author Feedback<br />';  
     $feedurl=~/^\/res\/(\w+)\/(\w+)\//;  
     $to{$2.':'.$1}=1;  
   }  
   if ($env{'form.question'}||$question) {  
     $typestyle.='Submitting as Question<br />';  
     foreach (split(/\,/,  
    $env{'course.'.$env{'request.course.id'}.'.question.email'})  
      ) {  
  my $rec=&secapply($_,$defaultflag);  
         if ($rec) { $to{$rec}=1; }  
     }   
   }  
   if ($env{'form.course'}||$course) {  
     $typestyle.='Submitting as Comment<br />';  
     foreach (split(/\,/,  
    $env{'course.'.$env{'request.course.id'}.'.comment.email'})  
      ) {  
  my $rec=&secapply($_,$defaultflag);  
         if ($rec) { $to{$rec}=1; }  
     }   
   }  
   if ($env{'form.policy'}||$policy) {  
     $typestyle.='Submitting as Policy Feedback<br />';  
     foreach (split(/\,/,  
    $env{'course.'.$env{'request.course.id'}.'.policy.email'})  
      ) {  
  my $rec=&secapply($_,$defaultflag);  
         if ($rec) { $to{$rec}=1; }  
     }   
   }  
   if ((scalar(%to) eq '0') && (!$defaultflag)) {  
      ($typestyle,%to)=  
  &decide_receiver($feedurl,$author,$question,$course,$policy,1);  
   }  
   return ($typestyle,%to);  
 }  
   
 sub feedback_available {  sub feedback_available {
     my ($question,$course,$policy)=@_;      my ($question,$course,$policy)=@_;
     my ($typestyle,%to)=&decide_receiver('',0,$question,$course,$policy);      my ($typestyle,%to)=&Apache::lonmsg::decide_receiver('',0,$question,
    $course,$policy);
     return scalar(%to);      return scalar(%to);
 }  }
   
 sub send_msg {  sub send_msg {
   my ($feedurl,$email,$citations,$attachmenturl,%to)=@_;    my ($title,$feedurl,$email,$citations,$attachmenturl,$symb,%to)=@_;
   my $status='';    my $status='';
   my $sendsomething=0;    my $sendsomething=0;
   foreach (keys %to) {    my $restitle = &get_resource_title($symb,$feedurl);
     if ($_) {    if ($title=~/^Error/) { $title=&mt('Feedback').': '.$title; }
       my $declutter=&Apache::lonnet::declutter($feedurl);    unless ($title=~/\w/) { $title=&mt('Feedback'); }
       unless (&Apache::lonmsg::user_normal_msg(split(/\:/,$_),    foreach my $key (keys(%to)) {
                'Feedback ['.$declutter.']',$email,$citations,$feedurl,      if ($key) {
                 $attachmenturl)=~/ok/) {        unless (&Apache::lonmsg::user_normal_msg(split(/\:/,$key),
  $status.='<br />'.&mt('Error sending message to').' '.$_.'<br />';                 $title.' ['.$restitle.']',$email,$citations,$feedurl,
                   $attachmenturl,undef,undef,$symb,$restitle)=~/ok/) {
    $status.='<br />'.&mt('Error sending message to').' '.$key.'<br />';
       } else {        } else {
  $sendsomething++;   $sendsomething++;
       }        }
Line 2473  sub send_msg { Line 2690  sub send_msg {
   }    }
   
     my %record=&Apache::lonnet::restore('_feedback');      my %record=&Apache::lonnet::restore('_feedback');
     my ($temp)=keys %record;      my ($temp)=keys(%record);
     unless ($temp=~/^error\:/) {      unless ($temp=~/^error\:/) {
        my %newrecord=();         my %newrecord=();
        $newrecord{'resource'}=$feedurl;         $newrecord{'resource'}=$feedurl;
Line 2516  sub adddiscuss { Line 2733  sub adddiscuss {
  $contrib{'anonymous'}='true';   $contrib{'anonymous'}='true';
     }      }
     if (($symb) && ($email)) {      if (($symb) && ($email)) {
           my $now = time;
         if ($env{'form.editdisc'}) {          if ($env{'form.editdisc'}) {
             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'} = $now;
             $contrib{'history'} = '';              $contrib{'history'} = '';
             my $numoldver = 0;              my $numoldver = 0;
             my ($oldsymb,$oldidx)=split(/\:\:\:/,$env{'form.editdisc'});              my ($oldsymb,$oldidx)=split(/\:\:\:/,$env{'form.editdisc'});
Line 2535  sub adddiscuss { Line 2752  sub adddiscuss {
             }              }
             if (defined($oldcontrib{$oldidx.':history'})) {              if (defined($oldcontrib{$oldidx.':history'})) {
                 if ($oldcontrib{$oldidx.':history'} =~ /:/) {                  if ($oldcontrib{$oldidx.':history'} =~ /:/) {
                     my @oldversions = split/:/,$oldcontrib{$oldidx.':history'};                      my @oldversions = split(/:/,$oldcontrib{$oldidx.':history'});
                     $numoldver = @oldversions;                      $numoldver = @oldversions;
                 } else {                  } else {
                     $numoldver = 1;                      $numoldver = 1;
Line 2560  sub adddiscuss { Line 2777  sub adddiscuss {
                 }                  }
             }              }
             $contrib{'history'} .= $oldcontrib{$oldidx.':timestamp'};              $contrib{'history'} .= $oldcontrib{$oldidx.':timestamp'};
             foreach (keys %contrib) {  
                 my $key = $oldidx.':'.&Apache::lonnet::escape($oldsymb).':'.$_;                                                                                 
                 $newcontrib{$key} = $contrib{$_};  
             }  
             my $put_reply = &Apache::lonnet::putstore($env{'request.course.id'},              my $put_reply = &Apache::lonnet::putstore($env{'request.course.id'},
                   \%newcontrib,                    $oldsymb,$oldidx,\%contrib,
                   $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)':'');
Line 2575  sub adddiscuss { Line 2788  sub adddiscuss {
                      $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 => $now);
         $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);
     unless ($temp=~/^error\:/) {      unless ($temp=~/^error\:/) {
        my %newrecord=();         my %newrecord=();
        $newrecord{'resource'}=$symb;         $newrecord{'resource'}=$symb;
Line 2596  sub adddiscuss { Line 2809  sub adddiscuss {
     return $status.'<br />';         return $status.'<br />';   
 }  }
   
   sub get_discussion_info {
       my ($idx,%contrib) = @_;
       my $changelast = 0;
       my $count = 0;
       my $hiddenflag = 0;
       my $deletedflag = 0;
       my ($hidden,$deleted,%info,$newlastdisc);
       my $version = $contrib{'version'};
       if ($version) {
           for (my $id=$version; $id>0; $id--) {
               my $vkeys=$contrib{$id.':keys'};
               my @keys=split(/:/,$vkeys);
               if (grep(/^hidden$/,@keys)) {
                   if (!$hiddenflag) {
                       $hidden = $contrib{$id.':hidden'};
                       $hiddenflag = 1;
                   }
               } elsif (grep(/^deleted$/,@keys)) {
                   if (!$deletedflag) {
                       $deleted = $contrib{$id.':deleted'};
                       $deletedflag = 1;
                   }
               } else {
                   if (($hidden !~/\.$id\./) && ($deleted !~/\.$id\./)) {
                       $count++;
                       $info{$count}{'id'} = $id;
                       $info{$count}{'timestamp'}=$contrib{$id.':timestamp'}; 
                   }
               }
           }
           if ($info{'1'}{'id'} == $idx) {
               $changelast = 1;
               if ($count > 1) { 
                   $newlastdisc =  $info{'2'}{'timestamp'};
               } else {
                   $newlastdisc = 0;
               }
           }
       }
       return ($changelast,$newlastdisc);
   }
   
 # ----------------------------------------------------------- Preview function  # ----------------------------------------------------------- Preview function
   
 sub show_preview {  sub show_preview {
     my $r=shift;      my ($r) = @_;
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
       my $start_page=
    &Apache::loncommon::start_page('Preview',undef,
          {'only_body'   => 1,});
   
     my $message=&clear_out_html($env{'form.comment'});      my $message=&clear_out_html($env{'form.comment'});
     &newline_to_br(\$message);      &newline_to_br(\$message);
     $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'},undef,1);
     $subject=~s/\n/\<br \/\>/g;      $subject=~s/\n/\<br \/\>/g;
     $subject=&Apache::lontexconvert::msgtexconverted($subject);      $subject=&Apache::lontexconvert::msgtexconverted($subject);
     my $html=&Apache::lonxml::xmlbegin();  
     $r->print($html.'<head>'.      my $end_page = &Apache::loncommon::end_page();
       '</head><body><table border="2"><tr><td>'.  
       '<b>Subject:</b> '.$subject.'<br /><br />'.      $r->print($start_page.'<table border="2"><tr><td>'.
       $message.'</td></tr></table></body></html>');        '<b>'.&mt('Subject').':</b> '.$subject.'<br /><br />'.
         $message.'</td></tr></table>'.$end_page);
 }  }
   
   
Line 2639  sub newline_to_br { Line 2899  sub newline_to_br {
 }  }
   
 sub generate_preview_button {  sub generate_preview_button {
       my ($formname,$fieldname)=@_;
       unless ($formname) { $formname='mailform'; }
       unless ($fieldname) { $fieldname='comment'; }
     my $pre=&mt("Show Preview and Check Spelling");      my $pre=&mt("Show Preview and Check Spelling");
     return(<<ENDPREVIEW);      return(<<ENDPREVIEW);
   <br />
 <form name="preview" action="/adm/feedback?preview=1" method="post" target="preview">  <form name="preview" action="/adm/feedback?preview=1" method="post" target="preview">
 <input type="hidden" name="subject">  <input type="hidden" name="subject">
 <input type="hidden" name="comment" />  <input type="hidden" name="comment" />
 <input type="button" value="$pre"  <input type="button" value="$pre"
 onClick="if (typeof(document.mailform.onsubmit)=='function') {document.mailform.onsubmit();};this.form.comment.value=document.mailform.comment.value;this.form.subject.value=document.mailform.subject.value;this.form.submit();" />  onClick="if (typeof(document.$formname.onsubmit)=='function') {document.$formname.onsubmit();};this.form.comment.value=document.$formname.$fieldname.value;this.form.subject.value=document.$formname.subject.value;this.form.submit();" />
 </form>  </form>
 ENDPREVIEW  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 $subject=&clear_out_html($orig_subject);      my %lt = &Apache::lonlocal::texthash(
                  'subj' => 'Subject',
                  'thfo' => 'The following attachments were part of the most recent saved version of this posting.',
                  'chth' => 'Check the checkboxes for any you wish to remove.',
                  'thef' => 'The following attachments have been uploaded for inclusion with this posting.',
                  'adda' => 'Add a new attachment to this post.',
                  'stch' => 'Store Changes',
                );
       my $js = <<END;
   <script type="text/javascript">
    function setAction () {
      document.modattachments.action = document.modattachments.origpage.value;
      document.modattachments.submit();
    }
   </script> 
   END
   
       my $start_page = 
    &Apache::loncommon::start_page('Discussion Post Attachments',$js);
   
       my $orig_subject = &unescape($env{'form.subject'});
       my $subject=&clear_out_html($orig_subject,undef,1);
     $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 $msg = '';      my $msg = '';
     my %attachments = ();      my %attachments = ();
     my %currattach = ();      my %currattach = ();
Line 2667  sub modify_attachments { Line 2951  sub modify_attachments {
         &extract_attachments($attachmenturls,$idx,$numoldver,\$msg,\%attachments,\%currattach,$currdelold);          &extract_attachments($attachmenturls,$idx,$numoldver,\$msg,\%attachments,\%currattach,$currdelold);
     }      }
     &Apache::lonenc::check_encrypt(\$symb);      &Apache::lonenc::check_encrypt(\$symb);
     my $html=&Apache::lonxml::xmlbegin();  
       my $end_page = 
    &Apache::loncommon::end_page();
          
     $r->print(<<END);      $r->print(<<END);
 $html  $start_page
 <head>  
 <title>Managing Attachments</title>  
 <script>  
  function setAction () {  
    document.modattachments.action = document.modattachments.origpage.value;  
    document.modattachments.submit();  
  }  
 </script>   
 </head>  
 $bodytag  
 <form name="modattachments" method="post" enctype="multipart/form-data" action="/adm/feedback?attach=$symb">  <form name="modattachments" method="post" enctype="multipart/form-data" action="/adm/feedback?attach=$symb">
  <table border="2">   <table border="2">
   <tr>    <tr>
Line 2688  $bodytag Line 2965  $bodytag
 END  END
     if ($idx) {      if ($idx) {
         if ($attachmenturls) {          if ($attachmenturls) {
             my @currold = keys %currattach;              my @currold = keys(%currattach);
             if (@currold > 0) {              if (@currold > 0) {
                 $r->print("The following attachments were part of the most recent saved version of this posting.<br />Check the checkboxes for any you wish to remove<br />\n");                    $r->print($lt{'thfo'}.'<br />'.$lt{'chth'}.'<br />'."\n");  
                 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#/([^/]+)$#;
Line 2700  END Line 2977  END
             }              }
         }          }
     }      }
     if (@{$currnewattach} > 0) {      if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) {
         $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($lt{'thef'}.'<br />'.$lt{'chth'}.'<br />'."\n");
         foreach (@{$currnewattach}) {          foreach my $attach (@{$currnewattach}) {
             $_ =~ m#/([^/]+)$#;              $attach =~ m#/([^/]+)$#;
             $r->print('<label><input type="checkbox" name="delnewattach" value="'.$_.'" />&nbsp;'.$1.'</label><br />'."\n");              $r->print('<label><input type="checkbox" name="delnewattach" value="'.$attach.'" />&nbsp;'.$1.'</label><br />'."\n");
         }          }
         $r->print("<br />");           $r->print("<br />"); 
     }      }
     $r->print(<<END);      $r->print(<<END);
    Add a new attachment to this post.&nbsp;<input type="file" name="addnewattach" /><input type="button" name="upload" value="Upload" onClick="this.form.submit()" />         $lt{'adda'}&nbsp;<input type="file" name="addnewattach" /><input type="button" name="upload" value="Upload" onClick="this.form.submit()" />    
    </td>     </td>
   </tr>    </tr>
  </table>   </table>
Line 2719  END Line 2996  END
 <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="blog" value="$env{'form.blog'}" />
 <input type="hidden" name="discuss" value="$env{'form.discuss'}" />  <input type="hidden" name="discuss" value="$env{'form.discuss'}" />
 END  END
     foreach (@{$currnewattach}) {      foreach my $item (@{$currnewattach}) {
         $r->print('<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n");          $r->print('<input type="hidden" name="currnewattach" value="'.$item.'" />'."\n");
     }      }
     foreach (@{$currdelold}) {      foreach my $item (@{$currdelold}) {
         $r->print('<input type="hidden" name="deloldattach" value="'.$_.'" />'."\n");          $r->print('<input type="hidden" name="deloldattach" value="'.$item.'" />'."\n");
     }      }
     $r->print(<<END);      $r->print(<<END);
  <input type="button" name="rtntoedit" value="Store Changes" onClick="setAction()"/>   <input type="button" name="rtntoedit" value="$lt{'stch'}" onClick="setAction()"/>
 </form>  </form>
 </body>  $end_page
 </html>  
 END  END
     return;      return;
 }  }
Line 2750  sub process_attachments { Line 3026  sub process_attachments {
         my @currnew = ();          my @currnew = ();
         foreach my $newone (@{$currnewattach}) {          foreach my $newone (@{$currnewattach}) {
             my $delflag = 0;              my $delflag = 0;
             foreach (@currdelnew) {              foreach my $item (@currdelnew) {
                 if ($newone eq $_) {                  if ($newone eq $item) {
                     $delflag = 1;                      $delflag = 1;
                     last;                      last;
                 }                  }
             }              }
             unless ($delflag) {              unless ($delflag) {
                 push @currnew, $newone;                  push(@currnew, $newone);
             }              }
         }          }
         @{$currnewattach} = @currnew;          @{$currnewattach} = @currnew;
Line 2766  sub process_attachments { Line 3042  sub process_attachments {
 }  }
   
 sub generate_attachments_button {  sub generate_attachments_button {
     my ($idx,$attachnum,$ressymb,$now,$currnewattach,$deloldattach,$numoldver,$mode) = @_;      my ($idx,$attachnum,$ressymb,$now,$currnewattach,$deloldattach,
           $numoldver,$mode,$blockblog) = @_;
     my $origpage = $ENV{'REQUEST_URI'};      my $origpage = $ENV{'REQUEST_URI'};
     my $att=$attachnum.' '.&mt("attachments");      my $att=$attachnum.' '.&mt("attachments");
       my %lt = &Apache::lonlocal::texthash(
                   'clic' => 'Click to add/remove attachments',
       ); 
     my $response = (<<END);      my $response = (<<END);
   <br />
 <form name="attachment" action="/adm/feedback?attach=$ressymb" method="post">  <form name="attachment" action="/adm/feedback?attach=$ressymb" method="post">
 Click to add/remove attachments:&nbsp;<input type="button" value="$att"  $lt{'clic'}:&nbsp;<input type="button" value="$att"
 onClick="if (typeof(document.mailform.onsubmit)=='function') {document.mailform.onsubmit();};this.form.comment.value=escape(document.mailform.comment.value);this.form.subject.value=escape(document.mailform.subject.value);  onClick="if (typeof(document.mailform.onsubmit)=='function') {document.mailform.onsubmit();};this.form.comment.value=escape(document.mailform.comment.value);this.form.subject.value=escape(document.mailform.subject.value);
 END  END
       if (!$blockblog) {
           $response .= 'setblogvalue();';
       }
     unless ($mode eq 'board') {      unless ($mode eq 'board') {
         $response .= 'javascript:anonchk();';          $response .= 'javascript:anonchk();';
     }      }
Line 2784  this.form.submit();" /> Line 3068  this.form.submit();" />
 <input type="hidden" name="timestamp" value="$now" />  <input type="hidden" name="timestamp" value="$now" />
 <input type="hidden" name="subject" />  <input type="hidden" name="subject" />
 <input type="hidden" name="comment" />  <input type="hidden" name="comment" />
 <input type="hidden" name="anondiscuss" value = "0" />  <input type="hidden" name="blog" value = "0" />
 <input type="hidden" name="discuss" value = "0" />  <input type="hidden" name="discuss" value = "0" />
 <input type="hidden" name="numoldver" value="$numoldver" />  <input type="hidden" name="numoldver" value="$numoldver" />
 ENDATTACH  ENDATTACH
     if (defined($deloldattach)) {      if (defined($deloldattach)) {
         if (@{$deloldattach} > 0) {          if (@{$deloldattach} > 0) {
             foreach (@{$deloldattach}) {              foreach my $delatt (@{$deloldattach}) {
                 $response .= '<input type="hidden" name="deloldattach" value="'.$_.'" />'."\n";                  $response .= '<input type="hidden" name="deloldattach" value="'.$delatt.'" />'."\n";
             }              }
         }          }
     }      }
     if (defined($currnewattach)) {      if (defined($currnewattach)) {
         if (@{$currnewattach} > 0) {          if (@{$currnewattach} > 0) {
             foreach (@{$currnewattach}) {              foreach my $attach (@{$currnewattach}) {
                 $response .= '<input type="hidden" name="currnewattach" value="'.$_.'" />'."\n";                  $response .= '<input type="hidden" name="currnewattach" value="'.$attach.'" />'."\n";
             }              }
         }          }
     }      }
Line 2810  sub extract_attachments { Line 3094  sub extract_attachments {
     my ($attachmenturls,$idx,$numoldver,$message,$attachments,$currattach,$currdelold) = @_;      my ($attachmenturls,$idx,$numoldver,$message,$attachments,$currattach,$currdelold) = @_;
     %{$attachments}=();      %{$attachments}=();
     &get_post_attachments($attachments,$attachmenturls);      &get_post_attachments($attachments,$attachmenturls);
     foreach my $id (sort keys %{$attachments}) {      foreach my $id (sort(keys(%{$attachments}))) {
         if (exists($$attachments{$id}{$numoldver})) {          if (exists($$attachments{$id}{$numoldver})) {
             if (defined($currdelold)) {              if (defined($currdelold)) {
                 if (@{$currdelold} > 0) {                  if (@{$currdelold} > 0) {
Line 2825  sub extract_attachments { Line 3109  sub extract_attachments {
             }              }
         }          }
     }      }
     my @attached = (sort { $a <=> $b } keys %{$currattach});      my @attached = (sort { $a <=> $b } keys(%{$currattach}));
     if (@attached == 1) {      if (@attached == 1) {
         my $id = $attached[0];          my $id = $attached[0];
         my $attachurl;          my $attachurl;
Line 2841  sub extract_attachments { Line 3125  sub extract_attachments {
                                $attachurl);                                 $attachurl);
     } elsif (@attached > 1) {      } elsif (@attached > 1) {
         $$message.='<ol>';          $$message.='<ol>';
         foreach (@attached) {          foreach my $attach (@attached) {
             my $id = $_;              my $id = $attach;
             my $attachurl = &HTML::Entities::decode($$attachments{$id}{'filename'});              my $attachurl = &HTML::Entities::decode($$attachments{$id}{'filename'});
             my ($fname)              my ($fname)
               =($attachurl=~m|/([^/]+)$|);                =($attachurl=~m|/([^/]+)$|);
Line 2869  sub construct_attachmenturl { Line 3153  sub construct_attachmenturl {
         $oldattachmenturl = $contrib{$idx.':attachmenturl'};          $oldattachmenturl = $contrib{$idx.':attachmenturl'};
         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'});
                 $currver = 1 + scalar(@oldversions);                  $currver = 1 + scalar(@oldversions);
             } else {              } else {
                 $currver = 2;                  $currver = 2;
Line 2882  sub construct_attachmenturl { Line 3166  sub construct_attachmenturl {
                 my %attachments = ();                  my %attachments = ();
                 my $prevver = $currver-1;                  my $prevver = $currver-1;
                 &get_post_attachments(\%attachments,$oldattachmenturl);                  &get_post_attachments(\%attachments,$oldattachmenturl);
                 my $numattach = scalar(keys %attachments);                  my $numattach = scalar(keys(%attachments));
                 $startnum += $numattach;                  $startnum += $numattach;
                 foreach my $num (sort {$a <=> $b} keys %attachments) {                  foreach my $num (sort {$a <=> $b} keys(%attachments)) {
                     $newattachmenturl .= '<attachment id="'.$num.'"><filename>'.$attachments{$num}{'filename'}.'</filename>';                      $newattachmenturl .= '<attachment id="'.$num.'"><filename>'.$attachments{$num}{'filename'}.'</filename>';
                     foreach $_ (sort {$a <=> $b} keys %{$attachments{$num}}) {                      foreach my $item (sort {$a <=> $b} keys(%{$attachments{$num}})) {
                         unless ($_ eq 'filename') {                          unless ($item eq 'filename') {
                             $newattachmenturl .= '<post id="'.$_.'">'.$attachments{$num}{$_}.'</post>';                              $newattachmenturl .= '<post id="'.$item.'">'.$attachments{$num}{$item}.'</post>';
                         }                          }
                     }                      }
                     if (grep/^$num$/,@{$keepold}) {                      if (grep/^$num$/,@{$keepold}) {
Line 2913  sub construct_attachmenturl { Line 3197  sub construct_attachmenturl {
     return $newattachmenturl;       return $newattachmenturl; 
 }  }
   
   sub add_blog_checkbox {
       my ($checkstatus);
       if ($env{'form.blog'}) {
           $checkstatus = 'checked="checked"';
       }
       my $output = '
   <script type="text/javascript">
   function setblogvalue() {
       if (document.mailform.blog.checked) {
           document.attachment.blog.value = 1;
       } else {
           document.attachment.blog.value = 0;
       }
   }
   </script><br />
   <label><input type="checkbox" name="blog" '.$checkstatus.' /> '.
   &mt('Add to my public course blog').'</label><br />'."\n";
       return $output;
   }
   
 sub has_discussion {  sub has_discussion {
     my $resourcesref = shift;      my $resourcesref = shift;
     my $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
Line 2920  sub has_discussion { Line 3224  sub has_discussion {
     foreach my $resource (@allres) {      foreach my $resource (@allres) {
         if ($resource->hasDiscussion()) {          if ($resource->hasDiscussion()) {
             my $ressymb = $resource->wrap_symb();              my $ressymb = $resource->wrap_symb();
             push @{$resourcesref}, $ressymb;              push(@{$resourcesref}, $ressymb);
         }          }
     }      }
     return;      return;
Line 2948  sub sort_filter_names { Line 3252  sub sort_filter_names {
                    );                     );
     %{$status_types} = (      %{$status_types} = (
                      all     => 'Roles of any status',                       all     => 'Roles of any status',
                      Active => 'Only active roles',                       Active  => 'Only active roles',
                      Expired => 'Only inactive roles'                       Expired => 'Only past roles',
                        Future  => 'Only future roles',
                    );                     );
 }  }
       
Line 2964  sub handler { Line 3269  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','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']);           ['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','groupick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export','sendmessageonly','group','ref']);
     my $group = $env{'form.group'};
     if ($env{'form.editdisc'}) {
         if (!(&editing_allowed($env{'form.editdisc'},$env{'form.group'}))) {
             my $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];
             my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
             my $feedurl=&Apache::lonnet::clutter($url);
             &redirect_back($r,$feedurl,&mt('Editing not permitted').'<br />',                     '0','0','','',$env{'form.previous'},undef,undef,undef,
                       undef,undef,undef,$group);
             return OK;
         }
     } 
   if ($env{'form.discsymb'}) {    if ($env{'form.discsymb'}) {
       my ($symb,$feedurl) = &get_feedurl_and_clean_symb($env{'form.discsymb'});        my ($symb,$feedurl) = &get_feedurl_and_clean_symb($env{'form.discsymb'});
       my $readkey = $symb.'_read';        my $readkey = $symb.'_read';
       my $chgcount = 0;        my $chgcount = 0;
       my %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 2989  sub handler { Line 3304  sub handler {
   \%readinghash,$env{'user.domain'},$env{'user.name'});    \%readinghash,$env{'user.domain'},$env{'user.name'});
       }        }
       &redirect_back($r,$feedurl,&mt('Marked postings read/unread').'<br />',        &redirect_back($r,$feedurl,&mt('Marked postings read/unread').'<br />',
      '0','0','',$env{'form.previous'},'','','',);       '0','0','','',$env{'form.previous'},'','','',
                        undef,undef,undef,$group);
       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');
         &Apache::loncommon::no_cache($r);
       $r->send_http_header;        $r->send_http_header;
       my $html=&Apache::lonxml::xmlbegin();  
       my $bodytag=&Apache::loncommon::bodytag('Discussion Post Versions');        $r->print(&Apache::loncommon::start_page('Discussion Post Versions'));
       $r->print(<<END);  
 $html  
 <head>  
 <title>Post Versions</title>  
 <meta http-equiv="pragma" content="no-cache" />  
 </head>  
 $bodytag  
 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 $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
         my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
       my ($symb,$idx)=split(/\:\:\:/,$env{'form.allversions'});        my ($symb,$idx)=split(/\:\:\:/,$env{'form.allversions'});
       ($symb)=&get_feedurl_and_clean_symb($symb);        ($symb)=&get_feedurl_and_clean_symb($symb);
         my $ressymb = &wrap_symb($symb);
         my $group = $env{'form.group'};
         my $seeid;
         if (($group ne '') && (($ressymb =~ m|^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|))) {
             if (&check_group_priv($group,'dgp') eq 'ok') {
                 $seeid = 1;
             }
         } else {
             $seeid = &Apache::lonnet::allowed('rin',$crs);
         }
       if ($idx > 0) {        if ($idx > 0) {
           my %messages = ();            my %messages = ();
           my %subjects = ();            my %subjects = ();
Line 3025  END Line 3346  END
                            $env{'course.'.$env{'request.course.id'}.'.num'});                             $env{'course.'.$env{'request.course.id'}.'.num'});
           $r->print(&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(&Apache::loncommon::end_page());
       return OK;        return OK;
   }    }
   if ($env{'form.posterlist'}) {    if ($env{'form.posterlist'}) {
Line 3041  END Line 3363  END
       $discinfo{$symb.'_userpick'} = join('&',@posters);        $discinfo{$symb.'_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',        &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0','',
      '',$env{'form.previous'},$env{'form.sortposts'},'','','',       '',$env{'form.previous'},$env{'form.sortposts'},'','','',
      $numpicks);       '',$numpicks,$group);
       return OK;        return OK;
   }    }
   if ($env{'form.applysort'}) {    if ($env{'form.applysort'}) {
       my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.applysort'});        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.applysort'});
       &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0',        &redirect_back($r,$feedurl,&mt('Changed sort/filter').'<br />','0','0','',
      '',$env{'form.previous'},$env{'form.sortposts'},       '',$env{'form.previous'},$env{'form.sortposts'},
      $env{'form.rolefilter'},$env{'form.statusfilter'},       $env{'form.rolefilter'},$env{'form.statusfilter'},
      $env{'form.sectionpick'});       $env{'form.sectionpick'},$env{'form.grouppick'},
                        undef,$group);
       return OK;        return OK;
   } elsif ($env{'form.cmd'} eq 'sortfilter') {    } elsif ($env{'form.cmd'} eq 'sortfilter') {
       my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});
Line 3062  END Line 3385  END
       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'}");
           }            }
Line 3077  END Line 3400  END
           'robb' => 'resources/bulletin boards.',            'robb' => 'resources/bulletin boards.',
           'twnp' => 'There are currently no resources or bulletin boards with unread discussion postings.'            'twnp' => 'There are currently no resources or bulletin boards with unread discussion postings.'
       );               );       
       foreach (@resources) {        foreach my $res (@resources) {
           my $ressymb=$_;            my $ressymb=$res;
   &Apache::lonenc::check_decrypt(\$ressymb);    &Apache::lonenc::check_decrypt(\$ressymb);
           my $lastkey = $ressymb.'_lastread';            my $lastkey = $ressymb.'_lastread';
           $discinfo{$lastkey} = $env{'form.navtime'};            $discinfo{$lastkey} = $env{'form.navtime'};
Line 3093  END Line 3416  END
       &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 $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
       my $html=&Apache::lonxml::xmlbegin();        my %onload;
         if ($env{'environment.remote'} ne 'off') {
     $onload{'onload'} =
         "if (window.name!='loncapaclient') { this.document.reldt.submit(); self.window.close(); }";
         }
   
         my $start_page=
     &Apache::loncommon::start_page('New posts marked as read',undef,
    {'redirect'    => [2,$feedurl],
     'only_body'   => 1,
     'add_entries' => \%onload});
         my $end_page = &Apache::loncommon::end_page();
       $r->print (<<ENDREDIR);        $r->print (<<ENDREDIR);
 $html  $start_page
 <head>  
 <title>New posts marked as read</title>  
 <meta http-equiv="pragma" content="no-cache" />  
 <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />  
 </head>  
 <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>  
 <img align="right" src="$logo" />  <img align="right" src="$logo" />
 $textline  $textline
 <form name="reldt" action="$feedurl" target="loncapaclient">  <form name="reldt" action="$feedurl" target="loncapaclient">
 </form>  </form>
 <br /><a href="$feedurl">Continue</a>  <br />
 </body>  $end_page
 </html>  
 ENDREDIR  ENDREDIR
       return OK;        return OK;
   } elsif ($env{'form.modifydisp'}) {    } elsif ($env{'form.modifydisp'}) {
Line 3152  ENDREDIR Line 3479  ENDREDIR
       my $previous=$env{'form.previous'};        my $previous=$env{'form.previous'};
       if ($env{'form.markondisp'}) { $previous=undef; }        if ($env{'form.markondisp'}) { $previous=undef; }
       &redirect_back($r,$feedurl,&mt('Changed display status').'<br />',        &redirect_back($r,$feedurl,&mt('Changed display status').'<br />',
      '0','0','',$previous);       '0','0','','',$previous,'','','','','','',$group);
       return OK;        return OK;
   } elsif (($env{'form.hide'}) || ($env{'form.unhide'})) {    } elsif (($env{'form.hide'}) || ($env{'form.unhide'})) {
 # ----------------------------------------------------------------- Hide/unhide  # ----------------------------------------------------------------- Hide/unhide
Line 3160  ENDREDIR Line 3487  ENDREDIR
       my ($symb,$idx)=split(/\:\:\:/,$entry);        my ($symb,$idx)=split(/\:\:\:/,$entry);
       ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);        ($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb);
   
         my $crs='/'.$env{'request.course.id'};
         if ($env{'request.course.sec'}) {
             $crs.='_'.$env{'request.course.sec'};
         }
         $crs=~s/\_/\//g;
         my $seeid=&Apache::lonnet::allowed('rin',$crs);
   
         if ($env{'form.hide'} && !$seeid && !(&editing_allowed($env{'form.hide'},$env{'form.group'}))) {
             &redirect_back($r,$feedurl,&mt('Deletion not permitted').'<br />',                 '0','0','','',$env{'form.previous'},'','','','',
                    undef,undef,$group,);
             return OK;
         }
   
       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'});
Line 3167  ENDREDIR Line 3507  ENDREDIR
       my $currenthidden=$contrib{'hidden'};        my $currenthidden=$contrib{'hidden'};
       my $currentstudenthidden=$contrib{'studenthidden'};        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'}) {        if ($env{'form.hide'}) {
   $currenthidden.='.'.$idx.'.';    $currenthidden.='.'.$idx.'.';
   unless ($seeid) {    unless ($seeid) {
Line 3186  ENDREDIR Line 3519  ENDREDIR
       if ( ($env{'form.hide'}) && (!$seeid) ) {        if ( ($env{'form.hide'}) && (!$seeid) ) {
   $newhash{'studenthidden'} = $currentstudenthidden;    $newhash{'studenthidden'} = $currentstudenthidden;
       }        }
         if ($env{'form.hide'}) {
             my $changelast = 0;
             my $newlast;
             ($changelast,$newlast) = &get_discussion_info($idx,%contrib);
             if ($changelast) {
                 &Apache::lonnet::put('discussiontimes',{$symb => $newlast},
                        $env{'course.'.$env{'request.course.id'}.'.domain'},
                        $env{'course.'.$env{'request.course.id'}.'.num'});
             }
         }
       &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},        &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},
                            $env{'course.'.$env{'request.course.id'}.'.domain'},                             $env{'course.'.$env{'request.course.id'}.'.domain'},
    $env{'course.'.$env{'request.course.id'}.'.num'});     $env{'course.'.$env{'request.course.id'}.'.num'});
   
       &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',        &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
      '0','0','',$env{'form.previous'});       '0','0','','',$env{'form.previous'},undef,undef,undef,
                        undef,undef,undef,$group);
       return OK;        return OK;
   } elsif ($env{'form.cmd'}=~/^(threadedoff|threadedon)$/) {    } elsif ($env{'form.cmd'}=~/^(threadedoff|threadedon)$/) {
       my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});
Line 3204  ENDREDIR Line 3547  ENDREDIR
   &Apache::lonnet::delenv('environment\.threadeddiscussion');    &Apache::lonnet::delenv('environment\.threadeddiscussion');
       }        }
       &redirect_back($r,$feedurl,&mt('Changed discussion view mode').'<br />',        &redirect_back($r,$feedurl,&mt('Changed discussion view mode').'<br />',
      '0','0','',$env{'form.previous'});       '0','0','','',$env{'form.previous'},undef,undef,undef,
                        undef,undef,undef,$group);
       return OK;        return OK;
   } elsif ($env{'form.deldisc'}) {    } elsif ($env{'form.deldisc'}) {
 # --------------------------------------------------------------- Hide for good  # --------------------------------------------------------------- Hide for good
Line 3213  ENDREDIR Line 3557  ENDREDIR
       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'});
         my ($changelast,$newlast) = &get_discussion_info($idx,%contrib);
         if ($changelast) {
             &Apache::lonnet::put('discussiontimes',{$symb => $newlast},
                      $env{'course.'.$env{'request.course.id'}.'.domain'},                   $env{'course.'.$env{'request.course.id'}.'.num'});
         }
       my %newhash=('deleted' => $contrib{'deleted'}.".$idx.");        my %newhash=('deleted' => $contrib{'deleted'}.".$idx.");
       &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},        &Apache::lonnet::store(\%newhash,$symb,$env{'request.course.id'},
    $env{'course.'.$env{'request.course.id'}.'.domain'},     $env{'course.'.$env{'request.course.id'}.'.domain'},
    $env{'course.'.$env{'request.course.id'}.'.num'});     $env{'course.'.$env{'request.course.id'}.'.num'});
       &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',        &redirect_back($r,$feedurl,&mt('Changed discussion status').'<br />',
      '0','0','',$env{'form.previous'});       '0','0','','',$env{'form.previous'},undef,undef,undef,
                        undef,undef,undef,$group);
       return OK;        return OK;
   } elsif ($env{'form.preview'}) {    } elsif ($env{'form.preview'}) {
 # -------------------------------------------------------- User wants a preview  # -------------------------------------------------------- User wants a preview
Line 3228  ENDREDIR Line 3578  ENDREDIR
 # -------------------------------------------------------- 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','discuss','blog']);
       my (@currnewattach,@currdelold,@keepold);        my (@currnewattach,@currdelold,@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;
Line 3262  ENDREDIR Line 3612  ENDREDIR
           $status=$Apache::inputtags::status[-1];            $status=$Apache::inputtags::status[-1];
       }        }
       my $discussion = &list_discussion($mode,$status,$symb);         my $discussion = &list_discussion($mode,$status,$symb); 
       my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion');        my $start_page = 
       $r->print($bodytag.$discussion);                                         &Apache::loncommon::start_page('Resource Feedback and Discussion');
         my $end_page = 
     &Apache::loncommon::end_page();
         $r->print($start_page.$discussion.$end_page);
       return OK;        return OK;
   } else {    } else {
 # ------------------------------------------------------------- Normal feedback  # ------------------------------------------------------------- Normal feedback
Line 3276  ENDREDIR Line 3629  ENDREDIR
       my $symb;        my $symb;
       if ($env{'form.replydisc'}) {        if ($env{'form.replydisc'}) {
   $symb=(split(/\:\:\:/,$env{'form.replydisc'}))[0];    $symb=(split(/\:\:\:/,$env{'form.replydisc'}))[0];
   my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);  
   $feedurl=&Apache::lonnet::clutter($url);  
       } elsif ($env{'form.editdisc'}) {        } 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'}) {        } elsif ($env{'form.origpage'}) {
   $symb="";     $symb=""; 
       } else {        } else {
Line 3289  ENDREDIR Line 3638  ENDREDIR
       }        }
       unless ($symb) {        unless ($symb) {
   $symb=$env{'form.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);        if (defined($symb)) {
             ($symb,$feedurl)=&get_feedurl_and_clean_symb($symb);
         } else {
             # backward compatibility (bulletin boards used to be 'wrapped')
             &Apache::lonenc::check_decrypt(\$feedurl);
             &dewrapper(\$feedurl);
         }
       my $goahead=1;        my $goahead=1;
       if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form|task)$/) {        if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form|task)$/) {
   unless ($symb) { $goahead=0; }    unless ($symb) { $goahead=0; }
       }        }
       # backward compatibility (bulletin boards used to be 'wrapped')  
       &dewrapper(\$feedurl);  
       if (!$goahead) {        if (!$goahead) {
           # Ambiguous Problem Resource            # Ambiguous Problem Resource
   $r->internal_redirect('/adm/ambiguous');    $r->internal_redirect('/adm/ambiguous');
Line 3319  ENDREDIR Line 3668  ENDREDIR
   &Apache::loncommon::content_type($r,'text/html');    &Apache::loncommon::content_type($r,'text/html');
   $r->send_http_header;    $r->send_http_header;
 # Unable to give feedback  # Unable to give feedback
             &Apache::lonenc::check_encrypt(\$feedurl);
   &no_redirect_back($r,$feedurl);    &no_redirect_back($r,$feedurl);
     return OK;
       }        }
 # --------------------------------------------------- Print login screen header  # --------------------------------------------------- Print login screen header
       unless ($env{'form.sendit'}) {        unless ($env{'form.sendit'}) {
             &Apache::lonenc::check_encrypt(\$feedurl);
   &Apache::loncommon::content_type($r,'text/html');    &Apache::loncommon::content_type($r,'text/html');
   $r->send_http_header;    $r->send_http_header;
             if (($env{'form.replydisc'}) || ($env{'form.editdisc'})) {
                 my ($blocked,$blocktext) = 
                        &Apache::loncommon::blocking_status('boards');
                 if ($blocked) {
                     $r->print(&blocked_reply_or_edit($blocktext));
                     return OK;
                 }
             }
   my $options=&screen_header($feedurl,$symb);    my $options=&screen_header($feedurl,$symb);
   if ($options) {    if ($options) {
       &mail_screen($r,$feedurl,$options);        &mail_screen($r,$feedurl,$options,$symb);
   } else {    } else {
       &fail_redirect($r,$feedurl);        &fail_redirect($r,$feedurl);
   }    }
Line 3340  ENDREDIR Line 3700  ENDREDIR
    $env{'request.course.id'});     $env{'request.course.id'});
   
 # Get output from resource  # Get output from resource
         &Apache::lonenc::check_encrypt(\$feedurl);
       my $usersaw=&resource_output($feedurl);        my $usersaw=&resource_output($feedurl);
   
 # 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 $usersymb = &Apache::lonenc::check_encrypt($symb);
                                    $symb,$env{'user.name'},$env{'user.domain'},        my $useranswer=
                    $env{'request.course.id'});            &Apache::loncommon::get_student_answers(
                 $usersymb,$env{'user.name'},$env{'user.domain'},
                 $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='';
Line 3376  ENDREDIR Line 3739  ENDREDIR
       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($message,$prevattempts,
      $usersaw,$useranswer);       $usersaw,$useranswer);
     
 # Who gets this?  # Who gets this?
       my ($typestyle,%to) = &decide_receiver($feedurl);        my ($typestyle,%to) = &Apache::lonmsg::decide_receiver($feedurl);
   
 # Actually send mail  # Actually send mail
       my ($status,$numsent)=&send_msg($feedurl,$email,$citations,        my ($status,$numsent)=&send_msg(&clear_out_html($env{'form.subject'},
       $attachmenturl,%to);        undef,1),
         $feedurl,$email,$citations,
         $attachmenturl,$usersymb,%to);
   
 # Discussion? Store that.  # Discussion? Store that.
   
       my $numpost=0;        my $numpost=0;
       if ($env{'form.discuss'} || $env{'form.anondiscuss'}) {        if (  ($env{'form.discuss'} ne ''
   my $subject = &clear_out_html($env{'form.subject'});       && $env{'form.discuss'} !~ /^(?:author|question|course|policy)/)
   my $anonmode=(defined($env{'form.anondiscuss'}));     || $env{'form.anondiscuss'} ne '') {
     my $subject = &clear_out_html($env{'form.subject'},undef,1);
     my $anonmode=($env{'form.discuss'} eq 'anon' || $env{'form.anondiscuss'} );
   $typestyle.=&adddiscuss($symb,$message,$anonmode,$attachmenturl,    $typestyle.=&adddiscuss($symb,$message,$anonmode,$attachmenturl,
   $subject);    $subject);
   $numpost++;    $numpost++;
       }        }
   
   # Add to blog?
   
         my $blog='';
         if ($env{'form.blog'}) {
     my $subject = &clear_out_html($env{'form.subject'},undef,1);
     $status.=&Apache::lonrss::addentry($env{'user.name'},
       $env{'user.domain'},
       'CourseBlog_'.$env{'request.course.id'},
       $subject,$message,$feedurl,'public');
     $blog='<br />'.&mt('Added to my course blog').'<br />';
         }
       
 # 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,$blog,$status,$env{'form.previous'},undef,undef,undef,undef,undef,undef,$group);
   }    }
   return OK;    return OK;
   }
   
   sub blocked_reply_or_edit {
       my ($blocktext) = @_;
       return 
         &Apache::loncommon::start_page('Resource Feedback and Discussion').
         $blocktext.'<br /><br /><a href="javascript:history.go(-1)">'.
         &mt('Back to previous page').
         &Apache::loncommon::end_page();
 }   } 
   
 sub wrap_symb {  sub wrap_symb {
Line 3437  sub get_feedurl_and_clean_symb { Line 3824  sub get_feedurl_and_clean_symb {
     my $feedurl = &get_feedurl($symb);      my $feedurl = &get_feedurl($symb);
     return ($symb,$feedurl);      return ($symb,$feedurl);
 }  }
   
   sub editing_allowed {
       my ($postid,$group) = @_;
       $postid = &unescape($postid);
       my $can_edit = 0;
       if ($group ne '') {
           my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
           my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
           if ($postid =~ m|^bulletin___\d+___adm/wrapper(/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard)|) {
               if (&check_group_priv($group,'egp') eq 'ok') {
                   $can_edit = 1;
               }
               return $can_edit;
           }     
       } 
       my $cid = $env{'request.course.id'};
       my $role = (split(/\./,$env{'request.role'}))[0];
       my $section = $env{'request.course.sec'};
       my $allow_editing_config = 
    $env{'course.'.$cid.'.allow_discussion_post_editing'};
       if ($allow_editing_config =~ m/^\s*yes\s*$/i) {
           $can_edit = 1;
       } else {
    foreach my $editor (split(/,/,$allow_editing_config)) {
       my ($editor_role,$editor_sec) = split(/:/,$editor);
       if ($editor_role eq $role
    && defined($editor_sec)
    && defined($section)
    && $editor_sec eq $section) {
    $can_edit = 1;
    last;
       }
       if ($editor_role eq $role
    && !defined($editor_sec)) {
    $can_edit = 1;
       }
    }
       }
       return $can_edit;
   }
   
   sub check_group_priv {
       my ($group,$grp_priv) = @_;
       foreach my $priv ('mdg','vcg') {
           my $checkcourse = $env{'request.course.id'}.
               ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'');
           if (&Apache::lonnet::allowed($priv,$checkcourse)) {
               return 'ok';
           }
       }
       if ($grp_priv && $group ne '') {
           if (&Apache::lonnet::allowed($grp_priv,$env{'request.course.id'}.'/'.$group)) {
               return 'ok';
           }
       }
       return '';
   }
   
   sub group_args { 
       my ($group) = @_;
       if ($group eq '') { return ''; }
       my $extra_args = '&amp;group='.$group;
       if (exists($env{'form.ref'})) {
           $extra_args .= '&amp;ref='.$env{'form.ref'};
       }
       return $extra_args;
   }
   
   sub get_resource_title {
       my ($symb,$feedurl) = @_;
       my ($restitle,$plainurl);
       if (defined($symb)) {
           my $plain_symb = &Apache::lonenc::check_decrypt($symb);
           $restitle = &Apache::lonnet::gettitle($plain_symb);
       }
       if (defined($feedurl)) {
           $plainurl = &Apache::lonenc::check_decrypt($feedurl);
       }
       if (!defined($restitle)) {
           if (defined($feedurl)) {
               $restitle = &Apache::lonnet::gettitle($plainurl);
           }
       }
       if ($plainurl ne $feedurl) {
           my ($plain_filename) = ($plainurl =~ m-/([^/]+)$-);
           if ($plain_filename eq $restitle) {
               $restitle = &mt('Untitled resource');
           }
       }
       if ($restitle eq '') {
           $restitle = &mt('Untitled resource');
       }
       return $restitle;
   }
   
 1;  1;
 __END__  __END__

Removed from v.1.168  
changed lines
  Added in v.1.242


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.