Diff for /loncom/interface/lonfeedback.pm between versions 1.17 and 1.92

version 1.17, 2001/11/06 11:15:09 version 1.92, 2004/06/04 19:27:33
Line 1 Line 1
 # The LearningOnline Network  # The LearningOnline Network
 # Feedback  # Feedback
 #  #
 # (Internal Server Error Handler  # $Id$
 #  #
 # (Login Screen  # Copyright Michigan State University Board of Trustees
 # 5/21/99,5/22,5/25,5/26,5/31,6/2,6/10,7/12,7/14,  
 # 1/14/00,5/29,5/30,6/1,6/29,7/1,11/9 Gerd Kortemeyer)  
 #  #
 # 3/1/1 Gerd Kortemeyer)  # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
 #  #
 # 3/1,2/3,2/5,2/6,2/8 Gerd Kortemeyer  # LON-CAPA is free software; you can redistribute it and/or modify
 # 2/9 Guy Albertelli  # it under the terms of the GNU General Public License as published by
 # 2/10 Gerd Kortemeyer  # the Free Software Foundation; either version 2 of the License, or
 # 2/13 Guy Albertelli  # (at your option) any later version.
 # 7/25 Gerd Kortemeyer  #
 # 7/26 Guy Albertelli  # LON-CAPA is distributed in the hope that it will be useful,
 # 7/26,8/10,10/1,11/5 Gerd Kortemeyer  # but WITHOUT ANY WARRANTY; without even the implied warranty of
   # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   # GNU General Public License for more details.
   #
   # You should have received a copy of the GNU General Public License
   # along with LON-CAPA; if not, write to the Free Software
   # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   #
   # /home/httpd/html/adm/gpl.txt
   #
   # http://www.lon-capa.org/
   #
   ###
   
 package Apache::lonfeedback;  package Apache::lonfeedback;
   
Line 24  use strict; Line 33  use strict;
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use Apache::lonmsg();  use Apache::lonmsg();
 use Apache::loncommon();  use Apache::loncommon();
   use Apache::lontexconvert();
   use Apache::lonlocal; # must not have ()
   use Apache::lonhtmlcommon();
   
   sub discussion_open {
       my ($status)=@_;
       if (defined($status) &&
    !($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
     || $status eq 'OPEN')) {
    &Apache::lonnet::logthis(" no open due to status $status");
    return 0;
       }
       my $close=&Apache::lonnet::EXT('resource.0.discussend');
       if (defined($close) && $close ne '' && $close < time) {
    &Apache::lonnet::logthis(" no open due to time ");
    return 0;
       }
       &Apache::lonnet::logthis(" open ");
       return 1;
   }
   
   sub discussion_visible {
       my ($status)=@_;
       if (not &discussion_open($status)) {
    my $hidden=&Apache::lonnet::EXT('resource.0.discusshide');
    if (lc($hidden) eq 'yes' or $hidden eq '' or !defined($hidden))  {
       &Apache::lonnet::logthis(" hidden ");
       return 0;
    }
       }
       &Apache::lonnet::logthis(" visible ");
       return 1;
   }
   
   sub list_discussion {
       my ($mode,$status,$symb)=@_;
   
       if (not &discussion_visible($status)) { return ''; }
       my @bgcols = ("#cccccc","#eeeeee");
       my $discussiononly=0;
       if ($mode eq 'board') { $discussiononly=1; }
       unless ($ENV{'request.course.id'}) { return ''; }
       my $crs='/'.$ENV{'request.course.id'};
       if ($ENV{'request.course.sec'}) {
    $crs.='_'.$ENV{'request.course.sec'};
       }                 
       $crs=~s/\_/\//g;
       unless ($symb) {
    $symb=&Apache::lonnet::symbread();
       }
       unless ($symb) { return ''; }
   
   # backward compatibility (bulletin boards used to be 'wrapped')
       my $ressymb=$symb;
       if ($mode eq 'board') {
           unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
               $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
           }
       }
   
   # Get discussion display settings for this discussion
       my $lastkey = $ressymb.'_lastread';
       my $showkey = $ressymb.'_showonlyunread';
       my $visitkey = $ressymb.'_visit';
       my $ondispkey = $ressymb.'_markondisp';
       my %dischash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$lastkey,$showkey,$visitkey,$ondispkey],$ENV{'user.domain'},$ENV{'user.name'});
       my %discinfo = ();
       my $showonlyunread = 0;
       my $markondisp = 0;
       my $prevread = 0;
       my $previous = 0;
       my $visit = 0;
       my $newpostsflag = 0;
   
   # Retain identification of "NEW" posts identified in last display, if continuing 'previous' browsing of posts.
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous']);
       $previous = $ENV{'form.previous'};
       if ($previous > 0) {
           $prevread = $previous;
       } elsif (defined($dischash{$lastkey})) {
           unless ($dischash{$lastkey} eq '') {
               $prevread = $dischash{$lastkey};
           }
       }
   
   # Get discussion display default settings for user
       my %userenv = &Apache::lonnet::get('environment',['discdisplay','discmarkread'],$ENV{'user.domain'},$ENV{'user.name'});
       my $discdisplay=$userenv{'discdisplay'};
       if ($discdisplay eq 'unread') {
           $showonlyunread = 1;
       }
       my $discmarkread=$userenv{'discmarkread'};
       if ($discmarkread eq 'ondisp') {
           $markondisp = 1;
       }
   
   # Override user's default if user specified display setting for this discussion
       if (defined($dischash{$ondispkey})) {
           $markondisp = $dischash{$ondispkey};
       }
       if ($markondisp) {
           $discinfo{$lastkey} = time;
       }
   
       if (defined($dischash{$showkey})) {
           $showonlyunread = $dischash{$showkey};
       }
   
       if (defined($dischash{$visitkey})) {
           $visit = $dischash{$visitkey};
       }
       $visit ++;
   
       my $seeid=&Apache::lonnet::allowed('rin',$crs);
       my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
    && ($symb=~/\.(problem|exam|quiz|assess|survey|form)$/));
       my @discussionitems=();
       my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
     $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
       my $visible=0;
       my @depth=();
       my @original=();
       my @index=();
       my @replies=();
       my %alldiscussion=();
       my %notshown = ();
       my %newitem = ();
       my $maxdepth=0;
   
       my $target='';
       unless ($ENV{'browser.interface'} eq 'textual' ||
       $ENV{'environment.remote'} eq 'off' ) {
    $target='target="LONcom"';
       }
       
       my $now = time;
       $discinfo{$visitkey} = $visit;
   
       &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
   
       if ($contrib{'version'}) {
           my $oldest = $contrib{'1:timestamp'};
           if ($prevread eq '0') {
               $prevread = $oldest-1;
           }
    for (my $id=1;$id<=$contrib{'version'};$id++) {
       my $idx=$id;
               my $posttime = $contrib{$idx.':timestamp'};
               if ($prevread <= $posttime) {
                   $newpostsflag = 1;
               }
       my $hidden=($contrib{'hidden'}=~/\.$idx\./);
       my $deleted=($contrib{'deleted'}=~/\.$idx\./);
       my $origindex='0.';
       if (($contrib{$idx.':replyto'}) && ($ENV{'environment.threadeddiscussion'})) {
   # this is a follow-up message
    $original[$idx]=$original[$contrib{$idx.':replyto'}];
    $depth[$idx]=$depth[$contrib{$idx.':replyto'}]+1;
    $origindex=$index[$contrib{$idx.':replyto'}];
    if ($depth[$idx]>$maxdepth) { $maxdepth=$depth[$idx]; }
       } else {
   # this is an original message
    $original[$idx]=0;
    $depth[$idx]=0;
       }
       if ($replies[$depth[$idx]]) {
    $replies[$depth[$idx]]++;
       } else {
    $replies[$depth[$idx]]=1;
       }
       unless ((($hidden) && (!$seeid)) || ($deleted)) {
    $visible++;
    my $message=$contrib{$idx.':message'};
    $message=~s/\n/\<br \/\>/g;
    $message=&Apache::lontexconvert::msgtexconverted($message);
                   my $subject=$contrib{$idx.':subject'};
                   if (defined($subject)) {
                       $subject=~s/\n/\<br \/\>/g;
                       $subject=&Apache::lontexconvert::msgtexconverted($subject);
                   }
    if ($contrib{$idx.':attachmenturl'}) {
       my ($fname)
                           =($contrib{$idx.':attachmenturl'}=~m|/([^/]+)$|);
       &Apache::lonnet::allowuploaded('/adm/feedback',
      $contrib{$idx.':attachmenturl'});
       $message.='<p>'.&mt('Attachment').
    ': <a href="'.$contrib{$idx.':attachmenturl'}.'"><tt>'.
    $fname.'</tt></a></p>';
    }
    if ($message) {
       if ($hidden) {
    $message='<font color="#888888">'.$message.'</font>';
       }
       my $screenname=&Apache::loncommon::screenname(
       $contrib{$idx.':sendername'},
       $contrib{$idx.':senderdomain'});
       my $plainname=&Apache::loncommon::nickname(
       $contrib{$idx.':sendername'},
       $contrib{$idx.':senderdomain'});
       
       my $sender=&mt('Anonymous');
       if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {
    $sender=&Apache::loncommon::aboutmewrapper(
    $plainname,
    $contrib{$idx.':sendername'},
    $contrib{$idx.':senderdomain'}).' ('.
    $contrib{$idx.':sendername'}.' at '.
    $contrib{$idx.':senderdomain'}.')';
    if ($contrib{$idx.':anonymous'}) {
       $sender.=' ['.&mt('anonymous').'] '.
    $screenname;
    }
    if ($seeid) {
       if ($hidden) {
    $sender.=' <a href="/adm/feedback?unhide='.
       $ressymb.':::'.$idx;
                                   if ($newpostsflag) {
                                       $sender .= '&previous='.$prevread;
                                   }
                                   $sender .= '">'.&mt('Make Visible').'</a>';
       } else {
    $sender.=' <a href="/adm/feedback?hide='.
       $ressymb.':::'.$idx;
                                   if ($newpostsflag) {
                                       $sender .= '&previous='.$prevread;
                                   }
                                   $sender .= '">'.&mt('Hide').'</a>';
       }                     
       $sender.=' <a href="/adm/feedback?deldisc='.
    $ressymb.':::'.$idx;
                                   if ($newpostsflag) {
                                       $sender .= '&previous='.$prevread;
                                   }
                                   $sender .= '">'.&mt('Delete').'</a>';
    }
       } else {
    if ($screenname) {
       $sender='<i>'.$screenname.'</i>';
    }
       }
       if (&discussion_open($status) &&
    &Apache::lonnet::allowed('pch',
    $ENV{'request.course.id'}.
    ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
    $sender.=' <a href="/adm/feedback?replydisc='.
       $ressymb.':::'.$idx;
                           if ($newpostsflag) {
                               $sender .= '&previous='.$prevread;
                           }
                           $sender .= '" '.$target.'>'.&mt('Reply').'</a>';
       }
       my $vgrlink;
       if ($viewgrades) {
    $vgrlink=&Apache::loncommon::submlink('Submissions',
               $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$symb);
       }
   #figure out at what position this needs to print
       my $thisindex=$idx;
       if ($ENV{'environment.threadeddiscussion'}) {
    $thisindex=$origindex.substr('00'.$replies[$depth[$idx]],-2,2);
       }
       $alldiscussion{$thisindex}=$idx;
       $index[$idx]=$thisindex;
                       my $spansize = 2;
                       if ($showonlyunread && $prevread > $posttime) {
                           $notshown{$idx} = 1;
                       } else {
                           if ($prevread > 0 && $prevread <= $posttime) {
                               $newitem{$idx} = 1;
                               $discussionitems[$idx] .= '
                                <p><table border="0" width="100%">
                                 <tr><td align="left"><font color="#FF0000"><b>NEW</b></font></td>';
                           } else {
                               $newitem{$idx} = 0;
                               $discussionitems[$idx] .= '
                                <p><table border="0" width="100%">
                                 <tr><td align="left">&nbsp;</td>';
                           }
                           $discussionitems[$idx] .= '<td align ="left">&nbsp;&nbsp;'.
                               '<b>'.$subject.'</b>&nbsp;&nbsp;'.
                               $sender.'</b> '.$vgrlink.' ('.
                               localtime($posttime).')</td></tr>'.
                               '</table><blockquote>'.$message.'</blockquote></p>';
                       }
                   }
               }
    }
       }
   
       my $discussion='';
   
       my $function = &Apache::loncommon::get_users_function();
       my $color = &Apache::loncommon::designparm($function.'.tabbg',
                                                       $ENV{'user.domain'});
       my %lt = &Apache::lonlocal::texthash(
           'cuse' => 'Current settings for this discussion',
           'allposts' => 'All posts',
           'unread' => 'New posts only',
           'ondisp' => 'Once displayed',
           'onmark' => 'Once marked read',
           'disa' => 'Posts to be displayed',
           'npce' => 'Posts cease to be marked "NEW"',
           'chgt' => 'Change to ',
       );
   
       my $currdisp = $lt{'allposts'};
       my $currmark = $lt{'onmark'};
       my $dispchange = $lt{'unread'};
       my $markchange = $lt{'ondisp'};
       my $displink = '/adm/feedback?onlyunread='.$ressymb;
       my $marklink = '/adm/feedback?markondisp='.$ressymb;
   
       if ($markondisp) {
           $currmark = $lt{'ondisp'};
           $markchange = $lt{'onmark'};
           $marklink = '/adm/feedback?markonread='.$ressymb;
           if ($newpostsflag) {
               $marklink .= '&previous='.$prevread;
           }
       }
   
       if ($showonlyunread) {
           $currdisp = $lt{'unread'};
           $dispchange = $lt{'allposts'};
           $displink = '/adm/feedback?allposts='.$ressymb;
       }
   
       if ($newpostsflag) {
           $displink .= '&previous='.$prevread;
       }
   
       if ($visible) {
   # Print the discusssion
    $discussion.='<table bgcolor="#AAAAAA" cellpadding="2" cellspacing="2" border="0">';
    my $colspan=$maxdepth+1;
           $discussion .= '<tr bgcolor="#FFFFFF"><td colspan="'.$colspan.'" valign="top">'.
           '<table border="0" bgcolor="#FFFFFF" width="100%" cellspacing="2" cellpadding="2">'.
           '<tr><td align="left"><b>'.$lt{'cuse'}.'</b></td><td>&nbsp;&nbsp;&nbsp;&nbsp;</td><td align="right"><b>'.$lt{'chgt'}.'</b></td></tr>'.
           '<tr><td>'.$lt{'disa'}.':&nbsp;<i>'.$currdisp.'</i></td><td>&nbsp;&nbsp;&nbsp;&nbsp;</td><td align="right"><a href="'.$displink.'">'.$dispchange.'</a></td></tr>'.
           '<tr><td>'.$lt{'npce'}.':&nbsp;<i>'.$currmark.'</i></td><td>&nbsp;&nbsp;&nbsp;&nbsp;</td><td align="right"><a href="'.$marklink.'">'.$markchange.'</a></td></tr>'.
           '</table></td></tr>'.
           '<tr><td bgcolor="#DDDDBB" colspan="'.$colspan.'">'.
           '<table border="0" width="100%" bgcolor="#DDDDBB"><tr>';
           if ($visible>2) {
       $discussion.='<td align="left">'.
               '<a href="/adm/feedback?threadedon='.$ressymb;
               if ($newpostsflag) {
                   $discussion .= '&previous='.$prevread;
               }
               $discussion .='">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.
               '<a href="/adm/feedback?threadedoff='.$ressymb;
               if ($newpostsflag) {
                   $discussion .= '&previous='.$prevread;
               }
               $discussion .='">'.&mt('Chronological View').'</a>&nbsp;&nbsp;</td>';
    } 
           if ($newpostsflag) {
               if (!$markondisp) {
                   $discussion .='<td align="right"><a href="/adm/feedback?markread='.$ressymb.'">'.&mt('Mark new posts as read').'</a>&nbsp;&nbsp;';
               } else {
                   $discussion .= '<td>&nbsp;</td>';
               }
           } else {
               $discussion .= '<td>&nbsp;</td>';
           }
           $discussion .= '</tr></table></td></tr>';
   
           my $numhidden = keys %notshown;
           if ($numhidden > 0) {
               my $colspan = $maxdepth+1;
               $discussion.="\n".'<tr><td bgcolor="#CCCCCC" colspan="'.$colspan.'">'.
                            '<a href="/adm/feedback?allposts='.$ressymb;
               if ($newpostsflag) {
                   $discussion .= '&previous='.$prevread;
               }
               $discussion .= '">'.&mt('Show all posts').'</a> '.&mt('to display').' '.
                            $numhidden.' '.&mt('previously viewed posts').
                            '<br/></td></tr>';
           }
    foreach (sort { $a <=> $b } keys %alldiscussion) {
               unless ($notshown{$alldiscussion{$_}} eq '1') {
           $discussion.="\n<tr>";
           my $thisdepth=$depth[$alldiscussion{$_}];
           for (1..$thisdepth) {
       $discussion.='<td>&nbsp;&nbsp;&nbsp;</td>';
           }
           my $colspan=$maxdepth-$thisdepth+1;
                   $discussion.='<td  bgcolor="'.$bgcols[$newitem{$alldiscussion{$_}}].'" colspan="'.$colspan.'">'.
                                $discussionitems[$alldiscussion{$_}].
                        '</td></tr>';
       }
           }
           $discussion.='</table><br /><br />';
       }
       if ($discussiononly) {
    $discussion.=(<<ENDDISCUSS);
   <form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data">
   <input type="submit" name="discuss" value="Post Discussion" />
   <input type="submit" name="anondiscuss" value="Post Anonymous Discussion" />
   <input type="hidden" name="symb" value="$ressymb" />
   <input type="hidden" name="sendit" value="true" />
   <br />
   <font size="1">Note: in anonymous discussion, your name is visible only to
   course faculty</font><br />
   <b>Title:</b>&nbsp;<input type="text" name="subject" value="" size="30" /><br /><br />
   <textarea name="comment" cols="60" rows="12" wrap="hard"></textarea>
   <p>
   Attachment (128 KB max size): <input type="file" name="attachment" />
   </p>
   </form>
   ENDDISCUSS
         $discussion.=&generate_preview_button();
       } else {
    if (&discussion_open($status) &&
       &Apache::lonnet::allowed('pch',
      $ENV{'request.course.id'}.
    ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
       $discussion.='<table bgcolor="#BBBBBB"><tr><td><a href="/adm/feedback?replydisc='.
    $symb.':::" '.$target.'>'.
    '<img src="/adm/lonMisc/chat.gif" border="0" />'.
    &mt('Post Discussion').'</a></td></tr></table>';
    }
       }
      return $discussion;
   }
   
 sub mail_screen {  sub mail_screen {
   my ($r,$feedurl,$options) = @_;    my ($r,$feedurl,$options) = @_;
     my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion',
                                             '','onLoad="window.focus();"');
     my $title=&Apache::lonnet::gettitle($feedurl);
     if (!$title) { $title = $feedurl; }
     my $quote='';
     my $subject = '';
     my $prevtag = '';
     if ($ENV{'form.replydisc'}) {
         my ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'});
         my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
         unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) {
     my $message=$contrib{$idx.':message'};
     $message=~s/\n/\<br \/\>/g;
     $quote='<blockquote>'.&Apache::lontexconvert::msgtexconverted($message).'</blockquote>';
             if ($idx > 0) {
                 $subject = 'Re: '.$contrib{$idx.':subject'};
             }
         }
         if ($ENV{'form.previous'}) {
             $prevtag = '<input type="hidden" name="previous" value="'.$ENV{'form.previous'}.'" />';
         }
     }
     my $latexHelp=&Apache::loncommon::helpLatexCheatsheet();
     my $htmlheader=&Apache::lonhtmlcommon::htmlareaheaders();
     my $send=&mt('Send');
   $r->print(<<ENDDOCUMENT);    $r->print(<<ENDDOCUMENT);
 <html>  <html>
 <head>  <head>
 <title>The LearningOnline Network with CAPA</title>  <title>The LearningOnline Network with CAPA</title>
 <meta http-equiv="pragma" content="no-cache"></meta>  <meta http-equiv="pragma" content="no-cache"></meta>
 <script>  $htmlheader
   <script type="text/javascript">
   //<!--
     function gosubmit() {      function gosubmit() {
         var rec=0;          var rec=0;
         if (typeof(document.mailform.elements.author)!="undefined") {          if (typeof(document.mailform.elements.author)!="undefined") {
Line 67  sub mail_screen { Line 531  sub mail_screen {
         }          }
   
         if (rec) {          if (rec) {
       document.mailform.onsubmit();
     document.mailform.submit();      document.mailform.submit();
         } else {          } else {
             alert('Please check a feedback type.');              alert('Please check a feedback type.');
  }   }
     }      }
   //-->
 </script>  </script>
 </head>  </head>
 <body bgcolor="#FFFFFF" onLoad="window.focus();">  $bodytag
 <img align=right src=/adm/lonIcons/lonlogos.gif>  <h2><tt>$title</tt></h2>
 <h1>Feedback</h1>  <form action="/adm/feedback" method="post" name="mailform"
 <h2><tt>$feedurl</tt></h2>  enctype="multipart/form-data">
 <form action="/adm/feedback" method=post name=mailform>  $prevtag
 <input type=hidden name=postdata value="$feedurl">  <input type="hidden" name="postdata" value="$feedurl" />
   <input type="hidden" name="replydisc" value="$ENV{'form.replydisc'}" />
 Please check at least one of the following feedback types:  Please check at least one of the following feedback types:
 $options<hr>  $options<hr />
 My question/comment/feedback:<p>  $quote
 <textarea name=comment cols=60 rows=10 wrap=hard>  <p>My question/comment/feedback:</p>
 </textarea><p>  <p>
 <input type=hidden name=sendit value=1>  $latexHelp
 <input type=button value="Send Feedback" onClick='gosubmit();'></input>  Title: <input type="text" name="subject" size="30" value="$subject" /></p>
   <p>
   <textarea name="comment" cols="60" rows="10" wrap="hard">
   </textarea></p>
   <p>
   Attachment (128 KB max size): <input type="file" name="attachment" />
   </p>
   <p>
   <input type="hidden" name="sendit" value="1" />
   <input type="button" value="$send" onClick='gosubmit();' />
   </p>
 </form>  </form>
 </body>  
 </html>  
 ENDDOCUMENT  ENDDOCUMENT
   $r->print(&generate_preview_button().
   &Apache::lonhtmlcommon::htmlareaactive().
   '</body></html>');
 }  }
   
 sub fail_redirect {  sub fail_redirect {
   my ($r,$feedurl) = @_;    my ($r,$feedurl) = @_;
     if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
   $r->print (<<ENDFAILREDIR);    $r->print (<<ENDFAILREDIR);
   <html>
 <head><title>Feedback not sent</title>  <head><title>Feedback not sent</title>
 <meta http-equiv="pragma" content="no-cache"></meta>  <meta http-equiv="pragma" content="no-cache" />
 <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl">  <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
 </head>  </head>
 <html>  
 <body bgcolor="#FFFFFF">  <body bgcolor="#FFFFFF">
 <img align=right src=/adm/lonIcons/lonlogos.gif>  <img align="right" src="/adm/lonIcons/lonlogos.gif" />
 <b>Sorry, no recipients  ...</b>  <b>Sorry, no recipients  ...</b>
 </body>  </body>
 </html>  </html>
Line 110  ENDFAILREDIR Line 589  ENDFAILREDIR
 }  }
   
 sub redirect_back {  sub redirect_back {
   my ($r,$feedurl,$typestyle,$sendsomething,$status) = @_;    my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous) = @_;
     my $prevtag = '';
     my $qrystr = '';
     if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
     if ($previous > 0) {
         $qrystr = 'previous='.$previous;
         if ($feedurl =~ /\?register=1/) {
             $feedurl .= '&'.$qrystr;
         } else {
             $feedurl .= '?'.$qrystr;
         }
         $prevtag = '<input type="hidden" name="previous" value="'.$previous.'" />';
     }
   $r->print (<<ENDREDIR);    $r->print (<<ENDREDIR);
   <html>
 <head>  <head>
 <title>Feedback sent</title>  <title>Feedback sent</title>
 <meta http-equiv="pragma" content="no-cache"></meta>  <meta http-equiv="pragma" content="no-cache" />
 <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl">  <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
 </head>  </head>
 <html>  <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>
 <body bgcolor="#FFFFFF">  <img align="right" src="/adm/lonIcons/lonlogos.gif" />
 <img align=right src=/adm/lonIcons/lonlogos.gif>  
 $typestyle  $typestyle
 <b>Sent $sendsomething message(s).</b>  <b>Sent $sendsomething message(s), and $sendposts post(s).</b>
 <font color=red>$status</font>  <font color="red">$status</font>
   <form name="reldt" action="$feedurl" target="loncapaclient">
   $prevtag
   </form>
 </body>  </body>
 </html>  </html>
 ENDREDIR  ENDREDIR
Line 131  ENDREDIR Line 625  ENDREDIR
 sub no_redirect_back {  sub no_redirect_back {
   my ($r,$feedurl) = @_;    my ($r,$feedurl) = @_;
   $r->print (<<ENDNOREDIR);    $r->print (<<ENDNOREDIR);
   <html>
 <head><title>Feedback not sent</title>  <head><title>Feedback not sent</title>
 <meta http-equiv="pragma" content="no-cache"></meta>  <meta http-equiv="pragma" content="no-cache" />
 ENDNOREDIR  ENDNOREDIR
   
   if ($feedurl!~/^\/adm\/feedback/) {     if ($feedurl!~/^\/adm\/feedback/) { 
Line 141  ENDNOREDIR Line 636  ENDNOREDIR
       
   $r->print (<<ENDNOREDIRTWO);    $r->print (<<ENDNOREDIRTWO);
 </head>  </head>
 <html>  <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { self.close(); }'>
 <body bgcolor="#FFFFFF">  <img align="right" src="/adm/lonIcons/lonlogos.gif" />
 <img align=right src=/adm/lonIcons/lonlogos.gif>  
 <b>Sorry, no feedback possible on this resource  ...</b>  <b>Sorry, no feedback possible on this resource  ...</b>
 </body>  </body>
 </html>  </html>
Line 151  ENDNOREDIRTWO Line 645  ENDNOREDIRTWO
 }  }
   
 sub screen_header {  sub screen_header {
   my ($feedurl) = @_;      my ($feedurl) = @_;
   my $options='';      my $msgoptions='';
   if (($feedurl=~/^\/res/) && ($feedurl!~/^\/res\/adm/)) {      my $discussoptions='';
     $options=       unless ($ENV{'form.replydisc'}) {
       '<p><input type=checkbox name=author> Feedback to resource author';   if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/)) {
   }      $msgoptions= 
   if ($ENV{'course.'.$ENV{'request.course.id'}.'.question.email'}) {   '<p><input type="checkbox" name="author" /> '.
     $options.=   &mt('Feedback to resource author').'</p>';
     '<br><input type=checkbox name=question> Question about resource content';   }
   }   if (&feedback_available(1)) {
   if ($ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'}) {      $msgoptions.=
     $options.=   '<br /><input type="checkbox" name="question" /> '.
       '<br><input type=checkbox name=course> '.   &mt('Question about resource content');
  'Question/Comment/Feedback about course content';   }
   }   if (&feedback_available(0,1)) {
   if ($ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'}) {      $msgoptions.=
     $options.=   '<br /><input type="checkbox" name="course" /> '.
       '<br><input type=checkbox name=policy> '.   &mt('Question/Comment/Feedback about course content');
  'Question/Comment/Feedback about course policy';   }
   }   if (&feedback_available(0,0,1)) {
   if ($ENV{'request.course.id'}) {      $msgoptions.=
     $options.='<br><input type=checkbox name=discuss> '.   '<br /><input type="checkbox" name="policy" /> '.
  '<b>Contribution to course discussion of resource</b>';   &mt('Question/Comment/Feedback about course policy');
   }   }
   if ($ENV{'request.course.id'}) {      }
     $options.='<br><input type=checkbox name=anondiscuss> '.      if ($ENV{'request.course.id'}) {
  '<b>Anonymous contribution to course discussion of resource</b>'.   if (&discussion_open() &&
         ' (name only visible to course faculty)';      &Apache::lonnet::allowed('pch',
   }       $ENV{'request.course.id'}.
   return $options;       ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
       $discussoptions='<input type="checkbox" name="discuss" onClick="this.form.anondiscuss.checked=false;" '.
    ($ENV{'form.replydisc'}?' checked="1"':'').' /> '.
    &mt('Contribution to course discussion of resource');
       $discussoptions.='<br /><input type="checkbox" name="anondiscuss" onClick="this.form.discuss.checked=false;" /> '.
    &mt('Anonymous contribution to course discussion of resource').
    ' <i>('.&mt('name only visible to course faculty').')</i>';
         }
       }
       if ($msgoptions) { $msgoptions='<h2><img src="/adm/lonMisc/feedback.gif" />'.&mt('Sending Messages').'</h2>'.$msgoptions; }
       if ($discussoptions) { 
    $discussoptions='<h2><img src="/adm/lonMisc/chat.gif" />'.&mt('Discussion Contributions').'</h2>'.$discussoptions; }
       return $msgoptions.$discussoptions;
 }  }
   
 sub resource_output {  sub resource_output {
   my ($feedurl) = @_;    my ($feedurl) = @_;
   my $usersaw=&Apache::lonnet::ssi($feedurl);    my $usersaw=&Apache::lonnet::ssi_body($feedurl);
   $usersaw=~s/\<body[^\>]*\>//gi;    $usersaw=~s/\<body[^\>]*\>//gi;
   $usersaw=~s/\<\/body\>//gi;    $usersaw=~s/\<\/body\>//gi;
   $usersaw=~s/\<html\>//gi;    $usersaw=~s/\<html\>//gi;
Line 197  sub resource_output { Line 703  sub resource_output {
 }  }
   
 sub clear_out_html {  sub clear_out_html {
   my $message=$ENV{'form.comment'};    my ($message,$override)=@_;
   $message=~s/\</\&lt\;/g;    unless (&Apache::lonhtmlcommon::htmlareablocked()) { return $message; }
   $message=~s/\>/\&gt\;/g;    my $cid=$ENV{'request.course.id'};
     if (($ENV{"course.$cid.allow_limited_html_in_feedback"} =~ m/yes/i) ||
         ($override)) {
         # allows <B> <I> <P> <A> <LI> <OL> <UL> <EM> <BR> <TT> <STRONG> 
         # <BLOCKQUOTE> <DIV .*> <DIV> <IMG> <M> <SPAN> <H1> <H2> <H3> <H4> <SUB>
         # <SUP>
         my %html=(B=>1, I=>1, P=>1, A=>1, LI=>1, OL=>1, UL=>1, EM=>1,
    BR=>1, TT=>1, STRONG=>1, BLOCKQUOTE=>1, DIV=>1, IMG=>1,
                   M=>1, SUB=>1, SUP=>1, SPAN=>1, 
    H1=>1, H2=>1, H3=>1, H4=>1, H5=>1);
   
         $message =~ s/\<(\/?\s*(\w+)[^\>\<]*)/
     {($html{uc($2)}&&(length($1)<1000))?"\<$1":"\&lt;$1"}/ge;
         $message =~ s/(\<?\s*(\w+)[^\<\>]*)\>/
     {($html{uc($2)}&&(length($1)<1000))?"$1\>":"$1\&gt;"}/ge;
     } else {
         $message=~s/\</\&lt\;/g;
         $message=~s/\>/\&gt\;/g;
     }
   return $message;    return $message;
 }  }
   
 sub assemble_email {  sub assemble_email {
   my ($feedurl,$message,$prevattempts,$usersaw)=@_;    my ($feedurl,$message,$prevattempts,$usersaw,$useranswer)=@_;
   my $email=<<"ENDEMAIL";    my $email=<<"ENDEMAIL";
 Refers to <a href="$feedurl">$feedurl</a>  Refers to <a href="$feedurl">$feedurl</a>
   
Line 213  ENDEMAIL Line 737  ENDEMAIL
     my $citations=<<"ENDCITE";      my $citations=<<"ENDCITE";
 <h2>Previous attempts of student (if applicable)</h2>  <h2>Previous attempts of student (if applicable)</h2>
 $prevattempts  $prevattempts
 <p><hr>  <br /><hr />
 <h2>Original screen output (if applicable)</h2>  <h2>Original screen output (if applicable)</h2>
 $usersaw  $usersaw
   <h2>Correct Answer(s) (if applicable)</h2>
   $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 '';
   }
   
 sub decide_receiver {  sub decide_receiver {
   my ($feedurl) = @_;    my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;
   my $typestyle='';    my $typestyle='';
   my %to=();    my %to=();
   if ($ENV{'form.author'}) {    if ($ENV{'form.author'}||$author) {
     $typestyle.='Submitting as Author Feedback<br>';      $typestyle.='Submitting as Author Feedback<br>';
     $feedurl=~/^\/res\/(\w+)\/(\w+)\//;      $feedurl=~/^\/res\/(\w+)\/(\w+)\//;
     $to{$2.':'.$1}=1;      $to{$2.':'.$1}=1;
   }    }
   if ($ENV{'form.question'}) {    if ($ENV{'form.question'}||$question) {
     $typestyle.='Submitting as Question<br>';      $typestyle.='Submitting as Question<br>';
     map {      foreach (split(/\,/,
       $to{$_}=1;     $ENV{'course.'.$ENV{'request.course.id'}.'.question.email'})
     } split(/\,/,       ) {
     $ENV{'course.'.$ENV{'request.course.id'}.'.question.email'});   my $rec=&secapply($_,$defaultflag);
   }          if ($rec) { $to{$rec}=1; }
   if ($ENV{'form.course'}) {      } 
     $typestyle.='Submitting as Comment<br>';    }
     map {    if ($ENV{'form.course'}||$course) {
       $to{$_}=1;      $typestyle.='Submitting as Comment<br />';
     } split(/\,/,      foreach (split(/\,/,
     $ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'});     $ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'})
   }       ) {
   if ($ENV{'form.policy'}) {   my $rec=&secapply($_,$defaultflag);
     $typestyle.='Submitting as Policy Feedback<br>';          if ($rec) { $to{$rec}=1; }
     map {      } 
       $to{$_}=1;    }
     } split(/\,/,    if ($ENV{'form.policy'}||$policy) {
     $ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'});      $typestyle.='Submitting as Policy Feedback<br />';
       foreach (split(/\,/,
      $ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'})
        ) {
    my $rec=&secapply($_,$defaultflag);
           if ($rec) { $to{$rec}=1; }
       } 
     }
     if ((scalar(%to) eq '0') && (!$defaultflag)) {
        ($typestyle,%to)=
    &decide_receiver($feedurl,$author,$question,$course,$policy,1);
   }    }
   return ($typestyle,%to);    return ($typestyle,%to);
 }  }
   
   sub feedback_available {
       my ($question,$course,$policy)=@_;
       my ($typestyle,%to)=&decide_receiver('',0,$question,$course,$policy);
       return scalar(%to);
   }
   
 sub send_msg {  sub send_msg {
   my ($feedurl,$email,$citations,%to)=@_;    my ($feedurl,$email,$citations,$attachmenturl,%to)=@_;
   my $status='';    my $status='';
   my $sendsomething=0;    my $sendsomething=0;
   map {    foreach (keys %to) {
     if ($_) {      if ($_) {
         my $declutter=&Apache::lonnet::declutter($feedurl);
       unless (&Apache::lonmsg::user_normal_msg(split(/\:/,$_),        unless (&Apache::lonmsg::user_normal_msg(split(/\:/,$_),
                'Feedback '.$feedurl,$email,$citations) eq 'ok') {                 'Feedback ['.$declutter.']',$email,$citations,$feedurl,
  $status.='<br>Error sending message to '.$_.'<br>';                  $attachmenturl)=~/ok/) {
    $status.='<br />'.&mt('Error sending message to').' '.$_.'<br />';
       } else {        } else {
  #$status.='<br>Message sent to '.$_.'<br>';  
  $sendsomething++;   $sendsomething++;
       }        }
     }      }
   } keys %to;           }
   
       my %record=&Apache::lonnet::restore('_feedback');
       my ($temp)=keys %record;
       unless ($temp=~/^error\:/) {
          my %newrecord=();
          $newrecord{'resource'}=$feedurl;
          $newrecord{'subnumber'}=$record{'subnumber'}+1;
          unless (&Apache::lonnet::cstore(\%newrecord,'_feedback') eq 'ok') {
      $status.='<br />'.&mt('Not registered').'<br />';
          }
       }
          
   return ($status,$sendsomething);    return ($status,$sendsomething);
 }  }
   
 sub adddiscuss {  sub adddiscuss {
     my ($symb,$email,$anon)=@_;      my ($symb,$email,$anon,$attachmenturl,$subject)=@_;
     my $status='';      my $status='';
       if (&discussion_open() &&
    &Apache::lonnet::allowed('pch',$ENV{'request.course.id'}.
           ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
   
     my %contrib=('message'      => $email,      my %contrib=('message'      => $email,
                  'sendername'   => $ENV{'user.name'},                   'sendername'   => $ENV{'user.name'},
                  'senderdomain' => $ENV{'user.domain'});                   'senderdomain' => $ENV{'user.domain'},
                    'screenname'   => $ENV{'environment.screenname'},
                    'plainname'    => $ENV{'environment.firstname'}.' '.
                      $ENV{'environment.middlename'}.' '.
                                      $ENV{'environment.lastname'}.' '.
                                      $ENV{'enrironment.generation'},
                    'attachmenturl'=> $attachmenturl,
                    'subject'      => $subject);
       if ($ENV{'form.replydisc'}) {
    $contrib{'replyto'}=(split(/\:\:\:/,$ENV{'form.replydisc'}))[1];
       }
     if ($anon) {      if ($anon) {
  $contrib{'anonymous'}='true';   $contrib{'anonymous'}='true';
     }      }
Line 285  sub adddiscuss { Line 873  sub adddiscuss {
         &Apache::lonnet::store(\%contrib,$symb,$ENV{'request.course.id'},          &Apache::lonnet::store(\%contrib,$symb,$ENV{'request.course.id'},
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                       $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});       $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
           my %storenewentry=($symb => time);
           $status.='<br />'.&mt('Updating discussion time').': '.
           &Apache::lonnet::put('discussiontimes',\%storenewentry,
                        $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
        $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
     }      }
     my $now=time;  
     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;
        $newrecord{'subnumber'}=$record{'subnumber'}+1;         $newrecord{'subnumber'}=$record{'subnumber'}+1;
        $status.=' '.&Apache::lonnet::cstore(\%newrecord,'_discussion');         $status.='<br />'.&mt('Registering').': '.
                  &Apache::lonnet::cstore(\%newrecord,'_discussion');
       }
       } else {
    $status.='Failed.';
     }      }
     return $status.'<br>';         return $status.'<br />';   
   }
   
   # ----------------------------------------------------------- Preview function
   
   sub show_preview {
       my $r=shift;
       my $message=&clear_out_html($ENV{'form.comment'});
       $message=~s/\n/\<br \/\>/g;
       $message=&Apache::lontexconvert::msgtexconverted($message);
       my $subject=&clear_out_html($ENV{'form.subject'});
       $subject=~s/\n/\<br \/\>/g;
       $subject=&Apache::lontexconvert::msgtexconverted($subject);
       $r->print('<table border="2"><tr><td>'.
          '<b>Subject:</b> '.$subject.'<br /><br />'.
          $message.'</td></tr></table>');
   }
   
   sub generate_preview_button {
       my $pre=&mt("Show Preview");
       return(<<ENDPREVIEW);
   <form name="preview" action="/adm/feedback?preview=1" method="post" target="preview">
   <input type="hidden" name="subject">
   <input type="hidden" name="comment" />
   <input type="button" value="$pre"
   onClick="document.mailform.onsubmit();this.form.comment.value=document.mailform.comment.value;this.form.subject.value=document.mailform.subject.value;this.form.submit();" />
   </form>
   ENDPREVIEW
 }  }
   
 sub handler {  sub handler {
   my $r = shift;    my $r = shift;
   if ($r->header_only) {    if ($r->header_only) {
      $r->content_type('text/html');       &Apache::loncommon::content_type($r,'text/html');
      $r->send_http_header;       $r->send_http_header;
      return OK;       return OK;
   }    }
   
 # --------------------------- Get query string for limited number of parameters  # --------------------------- Get query string for limited number of parameters
   
     map {     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
        my ($name, $value) = split(/=/,$_);           ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff','onlyunread','allposts','previous','markread','markonread','markondisp']);
        $value =~ tr/+/ /;  
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;  
        if (($name eq 'hide') || ($name eq 'unhide')) {  
            unless ($ENV{'form.'.$name}) {  
               $ENV{'form.'.$name}=$value;  
    }  
        }  
     } (split(/&/,$ENV{'QUERY_STRING'}));  
   
   if (($ENV{'form.hide'}) || ($ENV{'form.unhide'})) {    if (($ENV{'form.markondisp'}) || ($ENV{'form.markonread'})) {
   # ---------------------- Modify setting for identification of 'NEW' posts in this discussion
   
         &Apache::loncommon::content_type($r,'text/html');
         $r->send_http_header;
         my $symb=$ENV{'form.markondisp'}?$ENV{'form.markondisp'}:$ENV{'form.markonread'};
         my $ressymb = $symb;
         my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
         unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
             $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
         }
                                                                                             
         my %discinfo = ();
         my $lastkey = $ressymb.'_lastread';
         my $ondispkey = $ressymb.'_markondisp';
         if ($ENV{'form.markondisp'}) {
             $discinfo{$lastkey} = time;
             $discinfo{$ondispkey} = 1;
         } elsif ($ENV{'form.markonread'}) {
             if ( defined($ENV{'previous'}) ) {
                 $discinfo{$lastkey} = $ENV{'previous'};
             }
             $discinfo{$ondispkey} = 0;
         }
         &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
         if ($ENV{'form.markondisp'}) {
             &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'<br />','0','0');
         } else {
             &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'<br />','0','0','',$ENV{'form.previous'});
         }
         return OK;
     } elsif (($ENV{'form.allposts'}) || ($ENV{'form.onlyunread'})) {
   # ----------------------------------------------------------------- Modify display setting for this discussion 
         &Apache::loncommon::content_type($r,'text/html');
         $r->send_http_header;
         my $symb=$ENV{'form.allposts'}?$ENV{'form.allposts'}:$ENV{'form.onlyunread'};
         my $ressymb = $symb;
         my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
         unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
             $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
         }
         my %discinfo = ();
         if ($ENV{'form.allposts'}) {
             $discinfo{$ressymb.'_showonlyunread'} = 0;
         } elsif ($ENV{'form.onlyunread'}) {
             $discinfo{$ressymb.'_showonlyunread'} = 1;
         }
         &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
         &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'<br />','0','0','',$ENV{'form.previous'});
         return OK;
     } elsif ($ENV{'form.markread'}) {
   # ----------------------------------------------------------------- Mark new posts as read
         &Apache::loncommon::content_type($r,'text/html');
         $r->send_http_header;
         my $symb=$ENV{'form.markread'};
         my $ressymb = $symb;
         my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
         unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
             $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
         }
         my %discinfo = ();
         my $lastkey = $ressymb.'_lastread';
         $discinfo{$lastkey} = time;
         &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
         &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed reading status').'<br />','0','0');
         return OK;
     } elsif (($ENV{'form.hide'}) || ($ENV{'form.unhide'})) {
 # ----------------------------------------------------------------- Hide/unhide  # ----------------------------------------------------------------- Hide/unhide
     $r->content_type('text/html');      &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
   
     my $entry=$ENV{'form.hide'}?$ENV{'form.hide'}:$ENV{'form.unhide'};      my $entry=$ENV{'form.hide'}?$ENV{'form.hide'}:$ENV{'form.unhide'};
   
     my ($symb,$idx)=split(/\:\:\:/,$entry);      my ($symb,$idx)=split(/\:\:\:/,$entry);
     my ($map,$ind,$url)=split(/\_\_\_/,$symb);      my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
   
     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'},
Line 347  sub handler { Line 1028  sub handler {
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                       $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});       $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
   
     &redirect_back($r,'/res/'.$url,'Changed discussion status<p>','0');      &redirect_back($r,&Apache::lonnet::clutter($url),
          &mt('Changed discussion status').'<br />','0','0','',$ENV{'form.previous'});
     } elsif (($ENV{'form.threadedon'}) || ($ENV{'form.threadedoff'})) {
         &Apache::loncommon::content_type($r,'text/html');
         $r->send_http_header;
         if ($ENV{'form.threadedon'}) {
     &Apache::lonnet::put('environment',{'threadeddiscussion' => 'on'});
     &Apache::lonnet::appenv('environment.threadeddiscussion' => 'on');
         } else {
      &Apache::lonnet::del('environment',['threadeddiscussion']);
     &Apache::lonnet::delenv('environment\.threadeddiscussion');
         }
         my $symb=$ENV{'form.threadedon'}?$ENV{'form.threadedon'}:$ENV{'form.threadedoff'};
         my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
         &redirect_back($r,&Apache::lonnet::clutter($url),
        &mt('Changed discussion view mode').'<br />','0','0','',$ENV{'form.previous'});
     } elsif ($ENV{'form.deldisc'}) {
   # --------------------------------------------------------------- Hide for good
       &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
   
       my $entry=$ENV{'form.deldisc'};
   
             my ($symb,$idx)=split(/\:\:\:/,$entry);
       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
   
       my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
                        $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
        $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
   
           
       my $currentdeleted=$contrib{'deleted'};
       
       $currentdeleted.='.'.$idx.'.';
   
       my %newhash=('deleted' => $currentdeleted);
   
       &Apache::lonnet::store(\%newhash,$symb,$ENV{'request.course.id'},
                        $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
        $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
   
       &redirect_back($r,&Apache::lonnet::clutter($url),
          &mt('Changed discussion status').'<br />','0','0','',$ENV{'form.previous'});
     } elsif ($ENV{'form.preview'}) {
   # -------------------------------------------------------- User wants a preview
         $r->content_type('text/html');
         $r->send_http_header;
         &show_preview($r);
   } else {    } else {
 # ------------------------------------------------------------- Normal feedback  # ------------------------------------------------------------- Normal feedback
   my $feedurl=$ENV{'form.postdata'};    my $feedurl=$ENV{'form.postdata'};
   $feedurl=~s/^http\:\/\///;    $feedurl=~s/^http\:\/\///;
   $feedurl=~s/^$ENV{'SERVER_NAME'}//;    $feedurl=~s/^$ENV{'SERVER_NAME'}//;
   $feedurl=~s/^$ENV{'HTTP_HOST'}//;    $feedurl=~s/^$ENV{'HTTP_HOST'}//;
     $feedurl=~s/\?.+$//;
   
   my $symb=&Apache::lonnet::symbread($feedurl);    my $symb;
     if ($ENV{'form.replydisc'}) {
         $symb=(split(/\:\:\:/,$ENV{'form.replydisc'}))[0];
         my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
         $feedurl=&Apache::lonnet::clutter($url);
     } else {
         $symb=&Apache::lonnet::symbread($feedurl);
     }
     unless ($symb) {
         $symb=$ENV{'form.symb'};
         if ($symb) {
     my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
             $feedurl=&Apache::lonnet::clutter($url);
         }
     }
   my $goahead=1;    my $goahead=1;
   if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form)$/) {    if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form)$/) {
       unless ($symb) { $goahead=0; }        unless ($symb) { $goahead=0; }
   }    }
     # backward compatibility (bulltin boards used to be 'wrapped')
     if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
         $feedurl=~s|^/adm/wrapper||;
     }
   if ($goahead) {    if ($goahead) {
 # Go ahead with feedback, no ambiguous reference  # Go ahead with feedback, no ambiguous reference
     $r->content_type('text/html');      &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
       
     if (      if (
Line 374  sub handler { Line 1118  sub handler {
       )         ) 
       ||         || 
       ($ENV{'request.course.id'} && ($feedurl!~m:^/adm:))        ($ENV{'request.course.id'} && ($feedurl!~m:^/adm:))
         ||
         ($ENV{'request.course.id'} && ($symb=~/^bulletin\_\_\_/))
      ) {       ) {
 # --------------------------------------------------- Print login screen header  # --------------------------------------------------- Print login screen header
     unless ($ENV{'form.sendit'}) {      unless ($ENV{'form.sendit'}) {
Line 393  sub handler { Line 1139  sub handler {
 # Get output from resource  # Get output from resource
       my $usersaw=&resource_output($feedurl);        my $usersaw=&resource_output($feedurl);
   
   # Get resource answer (need to allow student to view grades for this to work)
         &Apache::lonnet::appenv(('allowed.vgr'=>'F'));
         my $useranswer=&Apache::loncommon::get_student_answers(
                          $symb,$ENV{'user.name'},$ENV{'user.domain'},
          $ENV{'request.course.id'});
         &Apache::lonnet::delenv('allowed.vgr');
   # Get attachments, if any, and not too large
         my $attachmenturl='';
         if ($ENV{'form.attachment.filename'}) {
     unless (length($ENV{'form.attachment'})>131072) {
         $attachmenturl=&Apache::lonnet::userfileupload('attachment',undef,'feedback');
     }
         }
 # Filter HTML out of message (could be nasty)  # Filter HTML out of message (could be nasty)
       my $message=&clear_out_html;        my $message=&clear_out_html($ENV{'form.comment'});
   
 # Assemble email  # Assemble email
       my ($email,$citations)=&assemble_email($feedurl,$message,$prevattempts,        my ($email,$citations)=&assemble_email($feedurl,$message,$prevattempts,
           $usersaw);            $usersaw,$useranswer);
    
 # Who gets this?  # Who gets this?
       my ($typestyle,%to) = &decide_receiver($feedurl);        my ($typestyle,%to) = &decide_receiver($feedurl);
   
 # Actually send mail  # Actually send mail
       my ($status,$numsent)=&send_msg($feedurl,$email,$citations,%to);        my ($status,$numsent)=&send_msg($feedurl,$email,$citations,
             $attachmenturl,%to);
   
 # Discussion? Store that.  # Discussion? Store that.
   
         my $numpost=0;
       if ($ENV{'form.discuss'}) {        if ($ENV{'form.discuss'}) {
   $typestyle.=&adddiscuss($symb,$message);            my $subject = &clear_out_html($ENV{'form.subject'});
     $typestyle.=&adddiscuss($symb,$message,0,$attachmenturl,$subject);
     $numpost++;
       }        }
   
       if ($ENV{'form.anondiscuss'}) {        if ($ENV{'form.anondiscuss'}) {
   $typestyle.=&adddiscuss($symb,$message,1);            my $subject = &clear_out_html($ENV{'form.subject'});
     $typestyle.=&adddiscuss($symb,$message,1,$attachmenturl,$subject);
     $numpost++;
       }        }
   
   
 # Receipt screen and redirect back to where came from  # Receipt screen and redirect back to where came from
       &redirect_back($r,$feedurl,$typestyle,$numsent,$status);        &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$status,$ENV{'form.previous'});
   
     }      }
    } else {     } else {
Line 427  sub handler { Line 1192  sub handler {
    }     }
   } else {    } else {
 # Ambiguous Problem Resource  # Ambiguous Problem Resource
     $r->internal_redirect('/adm/ambiguous');        if ( &Apache::lonnet::mod_perl_version() == 2 ) {
     &Apache::lonnet::cleanenv();
         }
         $r->internal_redirect('/adm/ambiguous');
   }    }
 }  }
   return OK;    return OK;
Line 435  sub handler { Line 1203  sub handler {
   
 1;  1;
 __END__  __END__
   
   
   
   

Removed from v.1.17  
changed lines
  Added in v.1.92


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.