Diff for /loncom/interface/lonfeedback.pm between versions 1.211 and 1.258

version 1.211, 2006/07/18 17:42:15 version 1.258, 2008/12/12 10:01:25
Line 44  use HTML::LCParser(); Line 44  use HTML::LCParser();
 use Apache::lonspeller();  use Apache::lonspeller();
 use Apache::longroup;  use Apache::longroup;
 use Cwd;  use Cwd;
 use lib '/home/httpd/lib/perl/';  
 use LONCAPA;  use LONCAPA;
   
 sub discussion_open {  sub discussion_open {
Line 75  sub discussion_visible { Line 74  sub discussion_visible {
   
 sub list_discussion {  sub list_discussion {
     my ($mode,$status,$ressymb,$imsextras,$group)=@_;      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 86  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 '<br />'.&send_message_link($ressymb);
           }
       }
     if ($group ne '' && $mode eq 'board') {      if ($group ne '' && $mode eq 'board') {
         if (&check_group_priv($group,'vgb') ne 'ok') {          if (&check_group_priv($group,'vgb') ne 'ok') {
             return '';              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 102  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 132  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','grouppick','totposters']);      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous','sortposts','rolefilter','statusfilter','sectionpick','grouppick','totposters']);
Line 161  sub list_discussion { Line 176  sub list_discussion {
     my ($classgroups,$studentgroups);      my ($classgroups,$studentgroups);
     if ($env{'form.rolefilter'}) {      if ($env{'form.rolefilter'}) {
         %roleshash = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);          %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,$keylist) =          my ($classlist,$keylist) =
Line 183  sub list_discussion { Line 198  sub list_discussion {
         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) =    ($classgroups,$studentgroups) = 
          &Apache::loncoursedata::get_group_memberships($classlist,$keylist,      &Apache::loncoursedata::get_group_memberships($classlist,$keylist,
                                                        $cdom,$cnum);    $cdom,$cnum);
     }      }
   
 # Get discussion display default settings for user  # Get discussion display default settings for user
Line 290  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 384  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,
     my $escsymb=&escape($ressymb);                                               $prevread,$markondisp);
     if ($visible>2) {              my $escsymb=&escape($ressymb);
  $discussion.='<td align="left">'.              my $numhidden = keys(%notshown);
     '<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>';  
   
             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.'">'.
Line 477  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 518  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 618  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 637  END Line 621  END
                     }                      }
                     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;';
                     }                      }
                     if ($statusfilter) {                      if ($statusfilter) {
                         $filterchoice .= '<i>'.&mt('status').'</i>-&nbsp;'.$status_types{$statusfilter};                          $filterchoice .= '<i>'.&mt('status').'</i>-&nbsp;'.$status_types{$statusfilter};
Line 653  END Line 637  END
                 }                  }
             }              }
             if ($dischash{$toggkey}) {              if ($dischash{$toggkey}) {
                 my $storebutton = &mt('Store read/unread changes');                  my $storebutton = &mt('Save read/unread changes');
                 $discussion.='<td align="right">'.                  $discussion.='<td align="right">'.
               '<input type="hidden" name="discsymb" value="'.$ressymb.'">'."\n".                '<input type="hidden" name="discsymb" value="'.$ressymb.'">'."\n".
               '<input type="button" name="readoptions" value="'.$storebutton.'"'.                '<input type="button" name="readoptions" value="'.$storebutton.'"'.
Line 665  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 699  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 713  END Line 701  END
     if ($discussiononly) {      if ($discussiononly) {
         my $now = time;          my $now = time;
         my $attachnum = 0;          my $attachnum = 0;
         my $currnewattach;          my $currnewattach = [];
         my $currdelold;          my $currdelold = [];
         my $comment = '';          my $comment = '';
         my $subject = '';          my $subject = '';
         if ($env{'form.origpage'}) {          if ($env{'form.origpage'}) {
Line 744  END Line 732  END
             }              }
  }   }
     } else {      } else {
  $discussion.='<table bgcolor="#BBBBBB"><tr><td>';          $discussion.='<div class="LC_feedback_link">';
         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.='<a href="/adm/feedback?replydisc='.   $discussion.= &send_feedback_link($ressymb,$target);
     &escape($ressymb).':::" '.$target.'>'.  
     '<img src="'.&Apache::loncommon::lonhttpdurl('/adm/lonMisc/chat.gif').'" border="0" />'.  
     &mt('Post Discussion').'</a><br />';  
             }              }
  }   }
  $discussion.='<a href="/adm/feedback?sendmessageonly=1&symb='.          if ($outputtarget ne 'tex') {
     &escape($ressymb).      $discussion.= &send_message_link($ressymb);
     '"><img src="'.&Apache::loncommon::lonhttpdurl('/adm/lonMisc/feedback.gif').'" border="0" />'.          }
     &mt('Send Message').'</a></td></tr></table>';          $discussion.='</div>';
     }      }
     return $discussion;      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_message_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;
   }
   
 sub postingform_display {  sub postingform_display {
     my ($mode,$ressymb,$now,$subject,$comment,$outputtarget,$attachnum,      my ($mode,$ressymb,$now,$subject,$comment,$outputtarget,$attachnum,
         $currnewattach,$currdelold,$group) = @_;          $currnewattach,$currdelold,$group) = @_;
     my $newattachmsg;      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);      my $postingform = (<<ENDDISCUSS);
 <form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data"> <input type="submit" name="discuss" value="Post Discussion" />  <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="Post Anonymous Discussion" /> <input type="hidden" name="symb" value="$ressymb" />  <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="sendit" value="true" />
 <input type="hidden" name="timestamp" value="$now" />  <input type="hidden" name="timestamp" value="$now" />
 <br /><a name="newpost"></a>  <br /><a name="newpost"></a>
 <font size="1">Note: in anonymous discussion, your name is visible only  <font size="1">$lt{'note'}</font><br />
 to course faculty</font><br />  <b>$lt{'title'}:</b>&nbsp;<input type="text" name="subject" value="$subject" size="30" /><br /><br />
 <b>Title:</b>&nbsp;<input type="text" name="subject" value="$subject" size="30" /><br /><br />  
 <textarea name="comment" cols="80" rows="14" wrap="hard">$comment</textarea>  <textarea name="comment" cols="80" rows="14" wrap="hard">$comment</textarea>
 ENDDISCUSS  ENDDISCUSS
     if ($env{'form.origpage'}) {      if ($env{'form.origpage'}) {
Line 794  ENDDISCUSS Line 859  ENDDISCUSS
     if ($group ne '') {      if ($group ne '') {
         $postingform .='<input type="hidden" name="group" value="'.$group.'" />';          $postingform .='<input type="hidden" name="group" value="'.$group.'" />';
     }      }
       my $blockblog = &Apache::loncommon::blocking_status('blogs');
       if (!$blockblog) {
           $postingform .= &add_blog_checkbox();
       }
     $postingform .= "</form>\n";      $postingform .= "</form>\n";
     if ($outputtarget ne 'tex') {      if ($outputtarget ne 'tex') {
         $postingform .= &generate_attachments_button('',$attachnum,$ressymb,          $postingform .= &generate_attachments_button('',$attachnum,$ressymb,
                                                      $now,$currnewattach,                                                       $now,$currnewattach,
                                                      $currdelold,'',$mode);                                                       $currdelold,'',$mode,
                                                        $blockblog);
         if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) {          if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) {
             $newattachmsg = '<br /><b>New attachments</b><br />';              $newattachmsg = '<br /><b>'.$lt{'newa'}.'</b><br />';
             if (@{$currnewattach} > 1) {              if (@{$currnewattach} > 1) {
                 $newattachmsg .= '<ol>';                  $newattachmsg .= '<ol>';
                 foreach my $item (@{$currnewattach}) {                  foreach my $item (@{$currnewattach}) {
Line 830  sub build_posting_display { Line 900  sub build_posting_display {
   $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 $see_anonymous = 
    &Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
   
     if ((@{$grouppick} == 0) || (grep(/^all$/,@{$grouppick}))) {      if ((@{$grouppick} == 0) || (grep(/^all$/,@{$grouppick}))) {
         $skip_group_check = 1;          $skip_group_check = 1;
     }      }
Line 880  sub build_posting_display { Line 953  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 919  sub build_posting_display { Line 992  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'}) || (&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) {          if (!$contrib{$idx.':anonymous'} || $see_anonymous) {
     $sender=&Apache::loncommon::aboutmewrapper(      $sender=&Apache::loncommon::aboutmewrapper(
  $plainname,   $plainname,
  $contrib{$idx.':sendername'},   $contrib{$idx.':sendername'},
  $contrib{$idx.':senderdomain'}).' ('.   $contrib{$idx.':senderdomain'}).' ('.
  $contrib{$idx.':sendername'}.' at '.   $contrib{$idx.':sendername'}.':'.
  $contrib{$idx.':senderdomain'}.')';   $contrib{$idx.':senderdomain'}.')';
     if ($contrib{$idx.':anonymous'}) {      if ($contrib{$idx.':anonymous'}) {
         $sender.=' <font color="red"><b>['.$$anonhash{$key}.']</b></font> '.          $sender.=' <font color="red"><b>['.$$anonhash{$key}.']</b></font> '.
     $screenname;      $screenname;
     }      }
       if ($see_anonymous) {
    $sender.=&Apache::loncommon::student_image_tag($contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'});
       }
 # Set up for sorting by domain, then username  # Set up for sorting by domain, then username
                             unless (defined($$usernamesort{$contrib{$idx.':senderdomain'}})) {                              unless (defined($$usernamesort{$contrib{$idx.':senderdomain'}})) {
                                 %{$$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 967  sub build_posting_display { Line 1042  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");
                             }                              }
Line 982  sub build_posting_display { Line 1057  sub build_posting_display {
                                     $sender .= '" '.$target.'>'.&mt('Edit').'</a>';                                      $sender .= '" '.$target.'>'.&mt('Edit').'</a>';
                                                                           
                                     unless ($seeid) {                                      unless ($seeid) {
                                         $sender.=" <a href=\"javascript:studentdelete('$escsymb','$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 1005  sub build_posting_display { Line 1081  sub build_posting_display {
                                     }                                      }
     $sender .= &group_args($group);      $sender .= &group_args($group);
                                     $sender .= '">'.&mt('Hide').'</a>';                                      $sender .= '">'.&mt('Hide').'</a>';
         }                               }
         $sender.=' <a href="/adm/feedback?deldisc='.                                  my $grpargs = &group_args($group);
         $escsymb.':::'.$idx;          $sender.= 
                                 if ($$newpostsflag) {                                      " <a href=\"javascript:verifydelete('seeiddelete','$escsymb','$idx','$$newpostsflag','$prevread','$grpargs')\">";
                                     $sender .= '&previous='.$prevread;                                  $sender .= &mt('Delete').'</a>';
                                 }  
  $sender .= &group_args($group);  
                                 $sender .= '">'.&mt('Delete').'</a>';  
                             }                              }
         } else {          } else {
     if ($screenname) {      if ($screenname) {
Line 1025  sub build_posting_display { Line 1098  sub build_posting_display {
                                 %{$$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 1034  sub build_posting_display { Line 1107  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");
                             }                              }
Line 1167  sub build_posting_display { Line 1240  sub build_posting_display {
                                 $$newitem{$idx} = 1;                                  $$newitem{$idx} = 1;
                                 $$discussionitems[$idx] .= '                                  $$discussionitems[$idx] .= '
                                  <p><table border="0" width="100%">                                   <p><table border="0" width="100%">
                                   <tr><td align="left"><font color="#FF0000"><b>NEW</b></font></td>';                                    <tr><td align="left"><font color="#FF0000"><b>'.&mt('NEW').'</b></font></td>';
                             } else {                              } else {
                                 $$newitem{$idx} = 0;                                  $$newitem{$idx} = 0;
                                 $$discussionitems[$idx] .= '                                  $$discussionitems[$idx] .= '
Line 1194  sub build_posting_display { Line 1267  sub build_posting_display {
                                 }                                  }
                                 $$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 1217  sub filter_regexp { Line 1290  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 1237  sub filter_regexp { Line 1310  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 1301  sub get_post_contents { Line 1374  sub get_post_contents {
         }          }
         &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 1328  sub get_post_contents { Line 1401  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 1339  sub get_post_contents { Line 1412  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 1363  END Line 1436  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 1386  sub replicate_attachments { Line 1459  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 1399  sub replicate_attachments { Line 1472  sub replicate_attachments {
 }  }
   
 sub mail_screen {  sub mail_screen {
   my ($r,$feedurl,$options) = @_;    my ($r,$feedurl,$options,$caller_symb,$attachmaxtext) = @_;
   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','blog','group','ref']);        &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','currnewattach','addnewattach','deloldattach','delnewattach','timestamp','idx','anondiscuss','discuss','blog','group','ref']);
   }    }
   
   my $title=&Apache::lonnet::gettitle($feedurl);    my %lt = &Apache::lonlocal::texthash(
   if (!$title) { $title = $feedurl; }              'plch' => 'Please check at least one of the following feedback types:',
               'myqu' => 'My question/comment/feedback:',
               'title' => 'Title',
               'reta' => 'Retained attachments',
               'atta' => 'Attachment',
              );
     my $restitle = &get_resource_title($caller_symb,$feedurl);
   my $quote='';    my $quote='';
   my $subject = '';    my $subject = '';
   my $comment = '';    my $comment = '';
Line 1471  END Line 1550  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 1480  END Line 1559  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 1544  END Line 1620  END
   }    }
   my $latexHelp=&Apache::loncommon::helpLatexCheatsheet();    my $latexHelp=&Apache::loncommon::helpLatexCheatsheet();
   my $send=&mt('Send');    my $send=&mt('Send');
     my $alert = &mt('Please select a feedback type.');
   my $js= <<END;    my $js= <<END;
 <script type="text/javascript">  <script type="text/javascript">
 //<!--  //<!--
Line 1574  END Line 1651  END
     }      }
     document.mailform.submit();      document.mailform.submit();
         } else {          } else {
             alert('Please select a feedback type.');              alert('$alert');
  }   }
     }      }
     $anonchk      $anonchk
Line 1588  END Line 1665  END
       &Apache::loncommon::start_page('Resource Feedback and Discussion',$js,        &Apache::loncommon::start_page('Resource Feedback and Discussion',$js,
      {'add_entries' => \%onload});       {'add_entries' => \%onload});
   
     if ($quote ne '') {
         &newline_to_br(\$quote);
         $quote='<blockquote>'.&Apache::lontexconvert::msgtexconverted($quote).'</blockquote>';
     }
   
   $r->print(<<END);    $r->print(<<END);
 $start_page  $start_page
 <h2><tt>$title</tt></h2>  <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 1607  END Line 1689  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 1621  Title: <input type="text" name="subject" Line 1703  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'} $attachmaxtext: <input type="file" name="attachment" />
 </p>  </p>
 END  END
     }      }
Line 1659  END Line 1741  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 1666  END Line 1749  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 .= '<br /><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 1683  END Line 1767  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 1718  sub print_display_options { Line 1802  sub print_display_options {
         'unread' => 'New posts only',          'unread' => 'New posts only',
         'unmark' => 'Posts not marked read',          'unmark' => 'Posts not marked read',
         'ondisp' => 'Once displayed',          'ondisp' => 'Once displayed',
         'onmark' => 'Once marked not NEW ',          'onmark' => 'Once marked not NEW',
         'toggon' => 'Shown',          'toggon' => 'Shown',
         'toggoff' => 'Not shown',          'toggoff' => 'Not shown',
         'disa' => 'Posts displayed?',          'disa' => 'Posts displayed?',
Line 1876  END Line 1960  END
        <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>
 END  END
       my $save = &mt('Save Changes');
     $r->print(&Apache::loncommon::end_data_table_row());      $r->print(&Apache::loncommon::end_data_table_row());
     $r->print(&Apache::loncommon::end_data_table());      $r->print(&Apache::loncommon::end_data_table());
     $r->print(<<END);      $r->print(<<END);
Line 1887  END Line 1972  END
 <input type="hidden" name="$dispchgB" value=""/>  <input type="hidden" name="$dispchgB" value=""/>
 <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="$save" onClick="javascript:setDisp()" />
 END  END
     if (exists($env{'form.group'})) {      if (exists($env{'form.group'})) {
         $r->print('<input type="hidden" name="group" value="'.$env{'form.group'}.'" />');          $r->print('<input type="hidden" name="group" value="'.$env{'form.group'}.'" />');
Line 1930  sub print_sortfilter_options { Line 2015  sub print_sortfilter_options {
         unshift(@sections,'all'); # Put 'all' at the front of the list          unshift(@sections,'all'); # Put 'all' at the front of the list
   
     }      }
     foreach (@sections) {      foreach my $sec (@sections) {
         $section_sel .= "  <option value=\"$_\" />$_\n";          $section_sel .= "  <option value=\"$sec\">$sec</option>\n";
     }      }
   
     if (&check_group_priv() eq 'ok') {      if (&check_group_priv() eq 'ok') {
Line 1956  sub print_sortfilter_options { Line 2041  sub print_sortfilter_options {
             $numgroupvis = 1;              $numgroupvis = 1;
         }          }
     }      }
     foreach (@groups) {      foreach my $group (@groups) {
         $group_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();
Line 1974  sub print_sortfilter_options { Line 2059  sub print_sortfilter_options {
         'spse' => 'Specific sections',          'spse' => 'Specific sections',
         'spgr' => 'Specific groups',          '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' => 'Save changes',
     );      );
   
     my %sort_types = ();      my %sort_types = ();
Line 2047  $start_page Line 2133  $start_page
  <tr>   <tr>
   <td align="center" valign="top">    <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" valign="top">    <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" valign="top">    <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="cr" />$role_types{'cr'}      <option value="cr">$role_types{'cr'}</option>
    </select>     </select>
   </td>    </td>
   <td>&nbsp;</td>    <td>&nbsp;</td>
Line 2095  $start_page Line 2182  $start_page
 <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  END
     if (exists($env{'form.group'})) {      if (exists($env{'form.group'})) {
         $r->print('<input type="hidden" name="group" value="'.$env{'form.group'}.'" />');          $r->print('<input type="hidden" name="group" value="'.$env{'form.group'}.'" />');
Line 2144  sub print_showposters { Line 2231  sub print_showposters {
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
                                           sele => 'Select',                                            sele => 'Select',
                                           full => 'Fullname',                                            full => 'Fullname',
                                           usdo => 'Username/domain',                                            usdo => 'Username:domain',
                                           post => 'Posts',                                            post => 'Posts',
                                         );                                          );
     if ($contrib{'version'}) {      if ($contrib{'version'}) {
Line 2169  sub print_showposters { Line 2256  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 2194  $start_page Line 2281  $start_page
       </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(&Apache::loncommon::start_data_table_row().                      $r->print(&Apache::loncommon::start_data_table_row().
       '<td align="right">'.$count.'</td>        '<td align="right">'.$count.'</td>
                                <td align="center"><label><input name="stuinfo" type="checkbox" value="'.$_.'" /></td>                                 <td align="center"><label><input name="stuinfo" type="checkbox" value="'.$user.'" /></td>
                                <td>'.$last.', '.$first.' ('.$uname.','.$udom.')</label></td>                                 <td>'.$last.', '.$first.' ('.$uname.':'.$udom.')</label></td>
                                <td>'.$postcounts{$_}.'</td>'.                                 <td>'.$postcounts{$user}.'</td>'.
       &Apache::loncommon::end_data_table_row());        &Apache::loncommon::end_data_table_row());
                 }                  }
             }              }
Line 2289  sub get_post_attachments { Line 2376  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');
   $r->print(&Apache::loncommon::start_page('Feedback not sent',undef,    $r->print(&Apache::loncommon::start_page('Feedback not sent',undef,
    {'redirect'  => [2,$feedurl],     {'redirect'  => [2,$feedurl],
     'only_body' => 1,}));      'only_body' => 1,}));
   $r->print(<<ENDFAILREDIR);    $r->print(<<ENDFAILREDIR);
 <img align="right" src="$logo" />  <img align="right" src="$logo" />
 <b>Sorry, no recipients  ...</b>  <b>$lt{'sorr'}</b>
 ENDFAILREDIR  ENDFAILREDIR
   $r->print(&Apache::loncommon::end_page());    $r->print(&Apache::loncommon::end_page());
 }  }
   
 sub redirect_back {  sub redirect_back {
   my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$blog,$status,$previous,$sort,$rolefilter,$statusfilter,$sectionpick,$grouppick,$numpicks,$group) = @_;    my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$blog,$status,$previous,$sort,$rolefilter,$statusfilter,$sectionpick,$grouppick,$numpicks,$group,$toolarge) = @_;
   my $sorttag = '';    my $sorttag = '';
   my $roletag = '';    my $roletag = '';
   my $statustag = '';    my $statustag = '';
Line 2340  sub redirect_back { Line 2430  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 2368  sub redirect_back { Line 2458  sub redirect_back {
           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 2396  sub redirect_back { Line 2486  sub redirect_back {
           $feedurl .= '?group='.$group.$refarg;            $feedurl .= '?group='.$group.$refarg;
       }        }
   }     } 
   $feedurl=&Apache::lonenc::check_encrypt($feedurl);    &Apache::lonenc::check_encrypt(\$feedurl);
   my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');    my $logo=&Apache::loncommon::lonhttpdurl('/adm/lonIcons/lonlogos.gif');
   my %onload;    my %onload;
   if ($env{'environment.remote'} ne 'off') {    if ($env{'environment.remote'} ne 'off') {
Line 2415  $start_page Line 2505  $start_page
 $typestyle  $typestyle
 <b>Sent $sendsomething message(s), and $sendposts post(s).</b>  <b>Sent $sendsomething message(s), and $sendposts post(s).</b>
 $blog  $blog
   $toolarge
 <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 2453  sub no_redirect_back { Line 2544  sub no_redirect_back {
               
   my $end_page = &Apache::loncommon::end_page();    my $end_page = &Apache::loncommon::end_page();
   
   $feedurl=&Apache::lonenc::check_encrypt($feedurl);    &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);
 $start_page  $start_page
Line 2474  sub screen_header { Line 2565  sub screen_header {
  '<p><label><input type="radio" name="discuss" value="author" /> '.   '<p><label><input type="radio" name="discuss" value="author" /> '.
  &mt('Feedback to resource author').'</label></p>';   &mt('Feedback to resource author').'</label></p>';
  }   }
           my %optionhash=();
           foreach my $type ('question','comment','policy') {
       $optionhash{$type}=$env{'course.'.$env{'request.course.id'}.'.'.$type.'.email.text'};
    }
  if (&feedback_available(1)) {   if (&feedback_available(1)) {
     $msgoptions.=      $msgoptions.=
  '<p><label><input type="radio" name="discuss" value="question" /> '.   '<p><label><input type="radio" name="discuss" value="question" /> '.
  &mt('Question about resource content').'</label></p>';   ($optionhash{'question'}?$optionhash{'question'}:&mt('Question about resource content')).'</label></p>';
  }   }
  if (&feedback_available(0,1)) {   if (&feedback_available(0,1)) {
     $msgoptions.=      $msgoptions.=
  '<p><label><input type="radio" name="discuss" value="course" /> '.   '<p><label><input type="radio" name="discuss" value="course" /> '.
  &mt('Question/Comment/Feedback about course content').   ($optionhash{'comment'}?$optionhash{'comment'}:&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="radio" name="discuss" value="policy" /> '.   '<p><label><input type="radio" name="discuss" value="policy" /> '.
  &mt('Question/Comment/Feedback about course policy').   ($optionhash{'policy'}?$optionhash{'policy'}:&mt('Question/Comment/Feedback about course policy')).
  '</label></p>';   '</label></p>';
  }   }
     }      }
     if (($env{'request.course.id'}) && (!$env{'form.sendmessageonly'})) {      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="radio" name="discuss" value="nonanon" checked="checked" /> '.      $discussoptions='<label><input type="radio" name="discuss" value="nonanon" checked="checked" /> '.
  &mt('Contribution to course discussion of resource');   &mt('Contribution to course discussion of resource');
     $discussoptions.='</label><br /><label><input type="radio" name="discuss" value="anon" /> '.          $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>';   '<a href="/adm/preferences?action=changescreenname">'.&mt('Change Screenname').'</a>';
               my $blockblog = &Apache::loncommon::blocking_status('blogs');
               if (!$blockblog) {
                   $discussoptions.= &add_blog_checkbox();
               }
         }          }
         $discussoptions.='<br /><label><input type="checkbox" name="blog" /> '.  
     &mt('Add to my public course blog').'</label>';  
     }      }
     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; }
     if ($discussoptions) {       if ($discussoptions) { 
Line 2545  sub clear_out_html { Line 2643  sub clear_out_html {
      H1=>1, H2=>1, H3=>1, H4=>1, H5=>1);       H1=>1, H2=>1, H3=>1, H4=>1, H5=>1);
   }    }
 # Do the substitution of everything that is not explicitly allowed  # Do the substitution of everything that is not explicitly allowed
   $message =~ s/\<(\/?\s*(\w*)[^\>\<]*)/    $message =~ s/\<(\/?\s*(\w+)[^\>\<]*)/
   {($html{uc($2)}&&(length($1)<1000))?"\<$1":"\&lt;$1"}/ge;    {($html{uc($2)}&&(length($1)<1000))?"\<$1":"\&lt;$1"}/ge;
   $message =~ s/(\<?\s*(\w*)[^\<\>]*)\>/    $message =~ s/(\<?\s*(\w+)[^\<\>]*)\>/
   {($html{uc($2)}&&(length($1)<1000))?"$1\>":"$1\&gt;"}/ge;    {($html{uc($2)}&&(length($1)<1000))?"$1\>":"$1\&gt;"}/ge;
   return $message;    return $message;
 }  }
   
 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.discuss'} eq 'author' ||$author) {  
     $typestyle.='Submitting as Author Feedback<br />';  
     $feedurl=~/^\/res\/(\w+)\/(\w+)\//;  
     $to{$2.':'.$1}=1;  
   }  
   if ($env{'form.discuss'} eq 'question' ||$question) {  
     $typestyle.=&mt('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.discuss'} eq 'course' ||$course) {  
     $typestyle.=&mt('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.discuss'} eq 'policy' ||$policy) {  
     $typestyle.=&mt('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 ($title,$feedurl,$email,$citations,$attachmenturl,%to)=@_;      my ($title,$feedurl,$email,$citations,$attachmenturl,$symb,%to)=@_;
   my $status='';      my $status='';
   my $sendsomething=0;      my $sendsomething=0;
   if ($title=~/^Error/) { $title=&mt('Feedback').': '.$title; }      my $restitle = &get_resource_title($symb,$feedurl);
   unless ($title=~/\w/) { $title=&mt('Feedback'); }      if ($title=~/^Error/) { $title=&mt('Feedback').': '.$title; }
   foreach (keys %to) {      unless ($title=~/\w/) { $title=&mt('Feedback'); }
     if ($_) {      foreach my $key (keys(%to)) {
       my $declutter=&Apache::lonnet::declutter($feedurl);   if ($key) {
       unless (&Apache::lonmsg::user_normal_msg(split(/\:/,$_),      my ($user,$domain) = split(/\:/,$key,2);
                $title.' ['.$declutter.']',$email,$citations,$feedurl,      if (!defined($user)) {
                 $attachmenturl)=~/ok/) {   $status.='<br />'.&mt('Error sending message to [_1], no user specified.',$key);
  $status.='<br />'.&mt('Error sending message to').' '.$_.'<br />';      } elsif (!defined($domain)) {
       } else {   $status.='<br />'.&mt('Error sending message to [_1], no domain specified.',$key);
  $sendsomething++;      } else {
       }   unless (&Apache::lonmsg::user_normal_msg($user,$domain,
    $title.' ['.$restitle.']',$email,$citations,$feedurl,
    $attachmenturl,undef,undef,$symb,$restitle)=~/ok/) {
       $status.='<br />'.&mt('Error sending message to').' '.$key.'<br />';
    } else {
       $sendsomething++;
    }
       }
    }
     }      }
   }  
   
     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;
        $newrecord{'subnumber'}=$record{'subnumber'}+1;   $newrecord{'subnumber'}=$record{'subnumber'}+1;
        unless (&Apache::lonnet::cstore(\%newrecord,'_feedback') eq 'ok') {   unless (&Apache::lonnet::cstore(\%newrecord,'_feedback') eq 'ok') {
    $status.='<br />'.&mt('Not registered').'<br />';      $status.='<br />'.&mt('Not registered').'<br />';
        }   }
     }      }
              
   return ($status,$sendsomething);      return ($status,$sendsomething);
 }  }
   
 sub adddiscuss {  sub adddiscuss {
Line 2731  sub adddiscuss { Line 2751  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'}) {
             $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 2749  sub adddiscuss { Line 2770  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 2785  sub adddiscuss { Line 2806  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 2806  sub adddiscuss { Line 2827  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) = @_;      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);
Line 2819  sub show_preview { Line 2886  sub show_preview {
     my $subject=&clear_out_html($env{'form.subject'},undef,1);      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 $start_page=  
  &Apache::loncommon::start_page('Preview',undef,  
        {'only_body'   => 1,});  
   
     my $end_page = &Apache::loncommon::end_page();      my $end_page = &Apache::loncommon::end_page();
   
     $r->print($start_page.'<table border="2"><tr><td>'.      $r->print($start_page.'<table border="2"><tr><td>'.
       '<b>Subject:</b> '.$subject.'<br /><br />'.        '<b>'.&mt('Subject').':</b> '.$subject.'<br /><br />'.
       $message.'</td></tr></table>'.$end_page);        $message.'</td></tr></table>'.$end_page);
 }  }
   
Line 2869  ENDPREVIEW Line 2933  ENDPREVIEW
 }  }
   
 sub modify_attachments {  sub modify_attachments {
     my ($r,$currnewattach,$currdelold,$symb,$idx,$attachmenturls)=@_;      my ($r,$currnewattach,$currdelold,$symb,$idx,$attachmenturls,
           $attachmaxtext,$toolarge)=@_;
   
       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' => 'Save 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 $orig_subject = &unescape($env{'form.subject'});
     my $subject=&clear_out_html($orig_subject,undef,1);      my $subject=&clear_out_html($orig_subject,undef,1);
     $subject=~s/\n/\<br \/\>/g;      $subject=~s/\n/\<br \/\>/g;
Line 2884  sub modify_attachments { Line 2970  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 $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 $end_page =       my $end_page = 
  &Apache::loncommon::end_page();   &Apache::loncommon::end_page();
                 
     $r->print(<<END);      $r->print(<<END);
 $start_page  $start_page
   $toolarge
 <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">   <br />
    <table class="LC_data_table">
   <tr>    <tr>
    <td>     <td colspan="2">
     <b>Subject:</b> $subject</b><br /><br />      <b>Subject:</b> $subject</b><br /><br />
 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 2920  END Line 2998  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()" />         </td></tr>
      <tr>
       <td>
      $lt{'adda'}</td><td><input type="file" name="addnewattach" /><input type="button" name="upload" value="Upload" onClick="this.form.submit()" />    
    </td>     </td>
   </tr>    </tr>
     <tr>
      <td colspan="2">$attachmaxtext</td>
     </tr>
  </table>   </table>
 <input type="hidden" name="subject" value="$env{'form.subject'}" />  <input type="hidden" name="subject" value="$env{'form.subject'}" />
 <input type="hidden" name="comment" value="$env{'form.comment'}" />  <input type="hidden" name="comment" value="$env{'form.comment'}" />
Line 2942  END Line 3026  END
 <input type="hidden" name="blog" value="$env{'form.blog'}" />  <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>
 $end_page  $end_page
 END  END
Line 2969  sub process_attachments { Line 3053  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 2985  sub process_attachments { Line 3069  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 />  <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 3010  this.form.submit();" /> Line 3101  this.form.submit();" />
 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 3030  sub extract_attachments { Line 3121  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 3045  sub extract_attachments { Line 3136  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 3061  sub extract_attachments { Line 3152  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 3089  sub construct_attachmenturl { Line 3180  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 3102  sub construct_attachmenturl { Line 3193  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 3133  sub construct_attachmenturl { Line 3224  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 3140  sub has_discussion { Line 3251  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 3168  sub sort_filter_names { Line 3279  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 3186  sub handler { Line 3298  sub handler {
   &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','groupick','posterlist','userpick','attach','origpage','currnewattach','deloldattach','keepold','allversions','export','sendmessageonly','group','ref']);           ['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'};    my $group = $env{'form.group'};
     my %attachmax = (
                       text => '(128 KB max size)',
                       num  => 131072,
                     );
   if ($env{'form.editdisc'}) {    if ($env{'form.editdisc'}) {
       if (!(&editing_allowed($env{'form.editdisc'},$env{'form.group'}))) {        if (!(&editing_allowed($env{'form.editdisc'},$env{'form.group'}))) {
           my $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];            my $symb=(split(/\:\:\:/,$env{'form.editdisc'}))[0];
Line 3201  sub handler { Line 3317  sub handler {
       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 3300  sub handler { Line 3416  sub handler {
       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 3315  sub handler { Line 3431  sub handler {
           '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 3434  ENDREDIR Line 3550  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'});
Line 3447  ENDREDIR Line 3572  ENDREDIR
       my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});        my ($symb,$feedurl)=&get_feedurl_and_clean_symb($env{'form.symb'});
       if ($env{'form.cmd'} eq 'threadedon') {        if ($env{'form.cmd'} eq 'threadedon') {
   &Apache::lonnet::put('environment',{'threadeddiscussion' => 'on'});    &Apache::lonnet::put('environment',{'threadeddiscussion' => 'on'});
   &Apache::lonnet::appenv('environment.threadeddiscussion' => 'on');    &Apache::lonnet::appenv({'environment.threadeddiscussion' => 'on'});
       } else {        } else {
    &Apache::lonnet::del('environment',['threadeddiscussion']);     &Apache::lonnet::del('environment',['threadeddiscussion']);
   &Apache::lonnet::delenv('environment\.threadeddiscussion');    &Apache::lonnet::delenv('environment\.threadeddiscussion');
Line 3463  ENDREDIR Line 3588  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'},
Line 3480  ENDREDIR Line 3610  ENDREDIR
       &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','discuss','blog']);        &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,$toolarge);
       &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) {            if (length($env{'form.addnewattach'})<=$attachmax{'num'}) {
               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);
             } else {
                 $toolarge = '<p><span class="LC_warning">'.&mt('Attachment not included - exceeded permitted length').'</span><br /></p>';
           }            }
       }        }
       my $attachmenturls;        my $attachmenturls;
Line 3499  ENDREDIR Line 3631  ENDREDIR
           $attachmenturls = $contrib{$idx.':attachmenturl'};            $attachmenturls = $contrib{$idx.':attachmenturl'};
       }        }
       &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx,        &modify_attachments($r,\@currnewattach,\@currdelold,$symb,$idx,
   $attachmenturls);    $attachmenturls,$attachmax{'text'},$toolarge);
       return OK;        return OK;
   } elsif ($env{'form.export'}) {    } elsif ($env{'form.export'}) {
       &Apache::loncommon::content_type($r,'text/html');        &Apache::loncommon::content_type($r,'text/html');
Line 3530  ENDREDIR Line 3662  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 3543  ENDREDIR Line 3671  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 3573  ENDREDIR Line 3701  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;    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,$attachmax{'text'});
   } else {    } else {
       &fail_redirect($r,$feedurl);        &fail_redirect($r,$feedurl);
   }    }
Line 3595  ENDREDIR Line 3733  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='';
         my $toolarge='';
       if (($env{'form.origpage'}) || ($env{'form.editdisc'}) ||        if (($env{'form.origpage'}) || ($env{'form.editdisc'}) ||
   ($env{'form.replydisc'})) {    ($env{'form.replydisc'})) {
   my ($symb,$idx);    my ($symb,$idx);
Line 3623  ENDREDIR Line 3765  ENDREDIR
   $symb=~s|(bulletin___\d+___)adm/wrapper/|$1|;    $symb=~s|(bulletin___\d+___)adm/wrapper/|$1|;
   $attachmenturl=&construct_attachmenturl(\@currnewattach,\@keepold,$symb,$idx);    $attachmenturl=&construct_attachmenturl(\@currnewattach,\@keepold,$symb,$idx);
       } elsif ($env{'form.attachment.filename'}) {        } elsif ($env{'form.attachment.filename'}) {
   unless (length($env{'form.attachment'})>131072) {    if (length($env{'form.attachment'})<=$attachmax{'num'}) {
       $attachmenturl=&Apache::lonnet::userfileupload('attachment',undef,'feedback');                my $now = time;
   }                my $subdir = 'feedback/'.$now;
         $attachmenturl=&Apache::lonnet::userfileupload('attachment',undef,$subdir);
     } else {
                 $toolarge = '<p><span class="LC_warning">'.&mt('Attachment not included - exceeded permitted length').'</span><br /></p>';
             }
       }        }
 # Filter HTML out of message (could be nasty)  # Filter HTML out of message (could be nasty)
       my $message=&clear_out_html($env{'form.comment'});        my $message=&clear_out_html($env{'form.comment'});
   
 # Assemble email  # Assemble email
       my ($email,$citations)=&assemble_email($feedurl,$message,$prevattempts,        my ($email,$citations)=&assemble_email($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(&clear_out_html($env{'form.subject'},        my ($status,$numsent)=&send_msg(&clear_out_html($env{'form.subject'},
       undef,1),        undef,1),
       $feedurl,$email,$citations,        $feedurl,$email,$citations,
       $attachmenturl,%to);        $attachmenturl,$usersymb,%to);
   
 # Discussion? Store that.  # Discussion? Store that.
       my $numpost=0;        my $numpost=0;
Line 3668  ENDREDIR Line 3814  ENDREDIR
       }        }
       
 # 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,$blog,$status,$env{'form.previous'},undef,undef,undef,undef,undef,undef,$group);        &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$blog,$status,$env{'form.previous'},undef,undef,undef,undef,undef,undef,$group,$toolarge);
   }    }
   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 3775  sub group_args { Line 3930  sub group_args {
     return $extra_args;      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__
   
   
   =pod
   
   =head1 NAME
   
   Apache::lonfeedback.pm
   
   =head1 SYNOPSIS
   
   Handles feedback from students to instructors and system administrators.
   
   Provides a screenshot of the current resource, as well as previous attempts if the resource was a homework.
   
   Used by lonmsg.pm.
   
   This is part of the LearningOnline Network with CAPA project
   described at http://www.lon-capa.org.
   
   =head1 OVERVIEW
   
   None
   
   =head1 SUBROUTINES
   
   =over
   
   =item discussion_open()
   
   =item discussion_visible()
   
   =item list_discussion()
   
   =item send_feedback_link()
   
   =item send_message_link()
   
   =item action_links_bar()
   
   =item postingform_display()
   
   =item build_posting_display
   
   =item filter_regexp()
   
   =item get_post_contents()
   
   =item replicate_attachments()
   
   =item mail_screen()
   
   =item print_display_options()
   
   =item print_sortfilter_options()
   
   =item print_showposters()
   
   =item get_post_versions()
   
   =item get_post_attachments()
   
   =item fail_redirect()
   
   =item redirect_back()
   
   =item no_redirect_back()
   
   =item screen_header()
   
   =item resource_output()
   
   =item clear_out_html()
   
   =item assemble_email()
   
   =item feedback_available()
   
   =item send_msg()
   
   =item adddiscuss()
   
   =item get_discussion_info()
   
   =item show_preview()
   
   =item newline_to_br()
   
   =item generate_preview_button()
   
   =item modify_attachments()
   
   =item process_attachments()
   
   =item generate_attachments_button()
   
   =item extract_attachments()
   
   =item construct_attachmenturl()
   
   =item add_blog_checkbox()
   
   =item has_discussion()
   
   =item sort_filter_names()
   
   =item handler()
   
   =item blocked_reply_or_edit()
   
   =item wrap_symb()
   
   =item dewrapper()
   
   =item get_feedurl()
   
   =item get_feedurl_and_clean_symb()
   
   =item editing_allowed()
   
   =item check_group_priv()
   
   =item group_args()
   
   =item get_resource_title()
   
   =back
   
   =cut

Removed from v.1.211  
changed lines
  Added in v.1.258


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.