Annotation of loncom/interface/lonfeedback.pm, revision 1.78

1.1       www         1: # The LearningOnline Network
                      2: # Feedback
                      3: #
1.78    ! raeburn     4: # $Id: lonfeedback.pm,v 1.77 2004/02/13 15:03:39 www Exp $
1.19      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.77      www        28: ###
1.7       albertel   29: 
1.1       www        30: package Apache::lonfeedback;
                     31: 
                     32: use strict;
                     33: use Apache::Constants qw(:common);
1.3       www        34: use Apache::lonmsg();
1.9       albertel   35: use Apache::loncommon();
1.33      www        36: use Apache::lontexconvert();
1.62      www        37: use Apache::lonlocal;
1.54      www        38: 
                     39: sub list_discussion {
1.57      www        40:     my ($mode,$status,$symb)=@_;
1.77      www        41: #    &Apache::lonnet::logthis("status is $status");
                     42:     if (!($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
                     43: 	  || $status eq 'OPEN')) {
1.75      albertel   44: 	return '';
                     45:     }
1.57      www        46:     my $discussiononly=0;
                     47:     if ($mode eq 'board') { $discussiononly=1; }
1.55      www        48:     unless ($ENV{'request.course.id'}) { return ''; }
                     49:     my $crs='/'.$ENV{'request.course.id'};
                     50:     if ($ENV{'request.course.sec'}) {
                     51: 	$crs.='_'.$ENV{'request.course.sec'};
                     52:     }                 
                     53:     $crs=~s/\_/\//g;
1.54      www        54:     unless ($symb) {
                     55: 	$symb=&Apache::lonnet::symbread();
                     56:     }
                     57:     unless ($symb) { return ''; }
1.78    ! raeburn    58: 
        !            59:     my %dischash = &Apache::lonnet::restore($symb,$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'});
        !            60:     my %readids = ();
        !            61:     my $showonlyunread;
        !            62:     foreach my $key (keys %dischash) {
        !            63:         if ($key eq 'showonlyunread') {
        !            64:             $showonlyunread = $dischash{$key};
        !            65:         } else {
        !            66:             if ($dischash{$key} eq 'read') {
        !            67:                 $readids{$key} = 1;
        !            68:             }
        !            69:         }
        !            70:     }
        !            71: 
1.54      www        72:     my $seeid=&Apache::lonnet::allowed('rin',$crs);
1.77      www        73:     my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
                     74: 	&& ($symb=~/\.(problem|exam|quiz|assess|survey|form)$/));
1.68      www        75:     my @discussionitems=();
1.74      www        76:     # backward compatibility (bulletin boards used to be 'wrapped')
1.73      albertel   77:     my $ressymb=$symb;
                     78:     if ($mode eq 'board') {
                     79: 	$ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
                     80:     }
                     81:     my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
1.54      www        82: 			  $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                     83: 			  $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
1.67      www        84:     my $visible=0;
1.68      www        85:     my @depth=();
                     86:     my @original=();
                     87:     my @index=();
                     88:     my @replies=();
                     89:     my %alldiscussion=();
                     90:     my $maxdepth=0;
                     91: 
1.69      www        92:     my $target='';
                     93:     unless ($ENV{'browser.interface'} eq 'textual' ||
                     94: 	    $ENV{'environment.remote'} eq 'off' ) {
                     95: 	$target='target="LONcom"';
                     96:     }
1.54      www        97:     if ($contrib{'version'}) {
1.64      www        98: 	for (my $id=1;$id<=$contrib{'version'};$id++) {
                     99: 	    my $idx=$id;
1.54      www       100: 	    my $hidden=($contrib{'hidden'}=~/\.$idx\./);
                    101: 	    my $deleted=($contrib{'deleted'}=~/\.$idx\./);
1.68      www       102: 	    my $origindex='0.';
1.69      www       103: 	    if (($contrib{$idx.':replyto'}) && ($ENV{'environment.threadeddiscussion'})) {
1.68      www       104: # this is a follow-up message
                    105: 		$original[$idx]=$original[$contrib{$idx.':replyto'}];
                    106: 		$depth[$idx]=$depth[$contrib{$idx.':replyto'}]+1;
                    107: 		$origindex=$index[$contrib{$idx.':replyto'}];
                    108: 		if ($depth[$idx]>$maxdepth) { $maxdepth=$depth[$idx]; }
                    109: 	    } else {
                    110: # this is an original message
                    111: 		$original[$idx]=0;
                    112: 		$depth[$idx]=0;
                    113: 	    }
                    114: 	    if ($replies[$depth[$idx]]) {
                    115: 		$replies[$depth[$idx]]++;
                    116: 	    } else {
                    117: 		$replies[$depth[$idx]]=1;
                    118: 	    }
1.54      www       119: 	    unless ((($hidden) && (!$seeid)) || ($deleted)) {
1.67      www       120: 		$visible++;
1.54      www       121: 		my $message=$contrib{$idx.':message'};
                    122: 		$message=~s/\n/\<br \/\>/g;
                    123: 		$message=&Apache::lontexconvert::msgtexconverted($message);
1.78    ! raeburn   124:                 my $subject=$contrib{$idx.':subject'};
        !           125:                 if (defined($subject)) {
        !           126:                     $subject=~s/\n/\<br \/\>/g;
        !           127:                     $subject=&Apache::lontexconvert::msgtexconverted($subject);
        !           128:                 }
1.54      www       129: 		if ($contrib{$idx.':attachmenturl'}) {
                    130: 		    my ($fname,$ft)
                    131:                         =($contrib{$idx.':attachmenturl'}=~/\/(\w+)\.(\w+)$/);
1.62      www       132: 		    $message.='<p>'.&mt('Attachment').': <a href="'.
1.54      www       133: 			&Apache::lonnet::tokenwrapper(
                    134:                                              $contrib{$idx.':attachmenturl'}).
1.63      albertel  135: 			'"><tt>'.$fname.'.'.$ft.'</tt></a></p>';
1.54      www       136: 		}
                    137: 		if ($message) {
                    138: 		    if ($hidden) {
                    139: 			$message='<font color="#888888">'.$message.'</font>';
                    140: 		    }
                    141: 		    my $screenname=&Apache::loncommon::screenname(
                    142: 					    $contrib{$idx.':sendername'},
                    143: 					    $contrib{$idx.':senderdomain'});
                    144: 		    my $plainname=&Apache::loncommon::nickname(
                    145: 					    $contrib{$idx.':sendername'},
                    146: 					    $contrib{$idx.':senderdomain'});
                    147: 		    
1.62      www       148: 		    my $sender=&mt('Anonymous');
1.54      www       149: 		    if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {
                    150: 			$sender=&Apache::loncommon::aboutmewrapper(
                    151: 					 $plainname,
                    152: 					 $contrib{$idx.':sendername'},
                    153: 					 $contrib{$idx.':senderdomain'}).' ('.
                    154: 					 $contrib{$idx.':sendername'}.' at '.
                    155: 					 $contrib{$idx.':senderdomain'}.')';
                    156: 			if ($contrib{$idx.':anonymous'}) {
1.62      www       157: 			    $sender.=' ['.&mt('anonymous').'] '.
1.54      www       158: 				$screenname;
                    159: 			}
                    160: 			if ($seeid) {
                    161: 			    if ($hidden) {
                    162: 				$sender.=' <a href="/adm/feedback?unhide='.
1.77      www       163: 				    $ressymb.':::'.$idx.'">'.&mt('Make Visible').'</a>';
1.54      www       164: 			    } else {
                    165: 				$sender.=' <a href="/adm/feedback?hide='.
1.77      www       166: 				    $ressymb.':::'.$idx.'">'.&mt('Hide').'</a>';
1.54      www       167: 			    }                     
                    168: 			    $sender.=' <a href="/adm/feedback?deldisc='.
1.77      www       169: 				$ressymb.':::'.$idx.'">'.&mt('Delete').'</a>';
1.64      www       170: 			}
1.54      www       171: 		    } else {
                    172: 			if ($screenname) {
                    173: 			    $sender='<i>'.$screenname.'</i>';
                    174: 			}
1.77      www       175: 		    }
                    176: 		    if (&Apache::lonnet::allowed('pch',
                    177: 						 $ENV{'request.course.id'}.
                    178: 						 ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
                    179: 			$sender.=' <a href="/adm/feedback?replydisc='.
                    180: 			    $ressymb.':::'.$idx.'" '.$target.'>'.&mt('Reply').'</a>';
1.54      www       181: 		    }
                    182: 		    my $vgrlink;
1.78    ! raeburn   183:                     my $ctlink;
        !           184:                     if ($readids{$idx} == 1) {
        !           185:                         $ctlink = '<b>'.&mt('Mark unread').'?</b>&nbsp;'.
        !           186:                             '<input type="checkbox" name="'.
        !           187:                             'postunread_'.$idx.'" />';
        !           188:                     } else {
        !           189:                         $ctlink = '<b>'.&mt('Mark read').'?</b>&nbsp;'.
        !           190:                             '<input type="checkbox" name="'.
        !           191:                             'postread_'.$idx.'" />';
        !           192:                     }
1.54      www       193: 		    if ($viewgrades) {
                    194: 			$vgrlink=&Apache::loncommon::submlink('Submissions',
                    195:             $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$symb);
                    196: 		    }
1.68      www       197: #figure out at what position this needs to print
                    198: 		    my $thisindex=$idx;
1.69      www       199: 		    if ($ENV{'environment.threadeddiscussion'}) {
1.68      www       200: 			$thisindex=$origindex.substr('00'.$replies[$depth[$idx]],-2,2);	
                    201: 		    }
                    202: 		    $alldiscussion{$thisindex}=$idx;
                    203: 		    $index[$idx]=$thisindex;
1.78    ! raeburn   204:                     $discussionitems[$idx]='<p><table border="0" width="100%">'.
        !           205:                         '<tr><td align="left"><b>'.$subject.'</b>&nbsp;&nbsp;'.
        !           206:                         $sender.'</b> '.$vgrlink.' ('.
        !           207:                         localtime($contrib{$idx.':timestamp'}).
        !           208:                         ')</td><td align="right">&nbsp;&nbsp;'.$ctlink.'</td></tr>';
        !           209:                     if ($showonlyunread && $readids{$idx}) {
        !           210:                         $discussionitems[$idx] .= '<tr><td colspan="2" align="right"><i><font size="-1">Check "Show all posts?" or "Mark unread?", then "Save read settings" to display message</font></i></td></tr></table>';
        !           211:                     } else {
        !           212:                         $discussionitems[$idx] .= '</table><blockquote>'.$message.'</blockquote></p>';
        !           213:                     }
        !           214:                 }
        !           215:             }
1.54      www       216: 	}
1.64      www       217:     }
1.67      www       218:     my $discussion='';
                    219:     if ($visible) {
1.69      www       220: # Print a the discusssion
1.78    ! raeburn   221:         $discussion .= '<form name="readchoices" method="post" action="/adm/feedback?chgreads='.$symb.'">';
1.67      www       222: 	$discussion.='<table bgcolor="#AAAAAA" cellpadding="2" cellspacing="2" border="0">';
1.69      www       223: 	if ($visible>2) {
                    224: 	    my $colspan=$maxdepth+1;
1.78    ! raeburn   225: my $showoption = '<tr><td align="right" bgcolor="#FFFFFF" colspan="'.$colspan.'">';
        !           226:             my $showflag = 'all';
        !           227:             if ($showonlyunread) {
        !           228:                 $showoption .= '<b>Show all posts?</b><input type="checkbox"
        !           229: name="allposts" value="1"></td></tr>';
        !           230:             } else {
        !           231:                 $showoption .= '<b>Show only unread posts?</b><input type="checkbox" name="onlyunread" value="1"></td></tr>';
        !           232:             }
        !           233:             $discussion.=$showoption;
1.69      www       234: 	    $discussion.='<tr><td bgcolor="DDDDBB" colspan="'.$colspan.'">'.
1.78    ! raeburn   235:             '<table border="0" width="100%" bgcolor="#DDDDBB"><tr><td align="left">'.
        !           236:             '<a href="/adm/feedback?threadedon='.$symb.'">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.
        !           237:             '<a href="/adm/feedback?threadedoff='.$symb.'">'.&mt('Chronological View').'</a>&nbsp;&nbsp;</td>'.
        !           238:             '<td align="right"><a href="/adm/feedback?markread='.$symb.'">'.&mt('Mark all read').'</a>&nbsp;&nbsp;'.
        !           239:             '<a href="/adm/feedback?markunread='.$symb.'">'.&mt('Mark all unread').'</a>&nbsp;&nbsp;'.
        !           240:             '</td></tr></table></td></tr>';
1.69      www       241: 	}
                    242: 
1.68      www       243: 	foreach (sort { $a <=> $b } keys %alldiscussion) {
1.69      www       244: 	    $discussion.="\n<tr>";
                    245: 	    my $thisdepth=$depth[$alldiscussion{$_}];
                    246: 	    for (1..$thisdepth) {
                    247: 		$discussion.='<td>&nbsp;&nbsp;&nbsp;</td>';
                    248: 	    }
                    249: 	    my $colspan=$maxdepth-$thisdepth+1;
1.78    ! raeburn   250:             $discussion.='<td  bgcolor="#CCCCCC" colspan="'.$colspan.'">'.
        !           251:                          $discussionitems[$alldiscussion{$_}].
        !           252: 	                 '</td></tr>';
1.67      www       253: 	}
1.78    ! raeburn   254:         my $colspan=$maxdepth+1;
        !           255:         $discussion.='<tr><td bgcolor="#FFFFFF" align="right" colspan="'.
        !           256:         $colspan.'"><br /><input type="hidden" name="storereads" value="0">'.            '<input type="hidden" name="discsymb" value="'.$symb.'">'.
        !           257:         '<input type="button" name="readoptions" '.
        !           258:         'value="Save read settings" onClick="this.form.storereads.value=1;this.form.submit();"></td></tr>';
        !           259:         $discussion .= '</table><br /><br /></form>';
1.54      www       260:     }
                    261:     if ($discussiononly) {
                    262: 	$discussion.=(<<ENDDISCUSS);
                    263: <form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data">
                    264: <input type="submit" name="discuss" value="Post Discussion" />
                    265: <input type="submit" name="anondiscuss" value="Post Anonymous Discussion" />
1.73      albertel  266: <input type="hidden" name="symb" value="$ressymb" />
1.54      www       267: <input type="hidden" name="sendit" value="true" />
                    268: <br />
                    269: <font size="1">Note: in anonymous discussion, your name is visible only to
                    270: course faculty</font><br />
1.78    ! raeburn   271: <b>Title:</b>&nbsp;<input type="text" name="subject" value="" size="30" /><br /><br />
1.63      albertel  272: <textarea name="comment" cols="60" rows="10" wrap="hard"></textarea>
1.54      www       273: <p>
                    274: Attachment (128 KB max size): <input type="file" name="attachment" />
                    275: </p>
                    276: </form>
                    277: ENDDISCUSS
                    278:       $discussion.=&generate_preview_button();
1.74      www       279:     } else {
                    280: 	if (&Apache::lonnet::allowed('pch',
                    281: 				   $ENV{'request.course.id'}.
                    282: 	($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
                    283: 			    $discussion.='<table bgcolor="#BBBBBB"><tr><td><a href="/adm/feedback?replydisc='.
                    284: 				$symb.':::" '.$target.'>'.
                    285: 				'<img src="/adm/lonMisc/chat.gif" border="0" />'.
                    286: 				&mt('Post Discussion').'</a></td></tr></table>';
                    287: 			}
                    288:     }
1.54      www       289:    return $discussion;
                    290: }
1.1       www       291: 
1.6       albertel  292: sub mail_screen {
                    293:   my ($r,$feedurl,$options) = @_;
1.45      www       294:   my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion',
                    295:                                           '','onLoad="window.focus();"');
1.51      albertel  296:   my $title=&Apache::lonnet::gettitle($feedurl);
                    297:   if (!$title) { $title = $feedurl; }
1.69      www       298:   my $quote='';
1.78    ! raeburn   299:   my $subject = '';
1.69      www       300:   if ($ENV{'form.replydisc'}) {
                    301:       my ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'});
                    302:       my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
                    303: 					   $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                    304: 					   $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
                    305:       unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) { 
                    306: 	  my $message=$contrib{$idx.':message'};
                    307: 	  $message=~s/\n/\<br \/\>/g;
                    308: 	  $quote='<blockquote>'.&Apache::lontexconvert::msgtexconverted($message).'</blockquote>';
1.78    ! raeburn   309:           $subject = 'Re: '.$contrib{$idx.':subject'};
1.69      www       310:       }
                    311:   }
1.47      bowersj2  312:   my $latexHelp = Apache::loncommon::helpLatexCheatsheet();
1.74      www       313:   my $send=&mt('Send');
1.6       albertel  314:   $r->print(<<ENDDOCUMENT);
1.1       www       315: <html>
                    316: <head>
                    317: <title>The LearningOnline Network with CAPA</title>
1.7       albertel  318: <meta http-equiv="pragma" content="no-cache"></meta>
1.63      albertel  319: <script type="text/javascript">
                    320: //<!--
1.5       www       321:     function gosubmit() {
                    322:         var rec=0;
1.12      albertel  323:         if (typeof(document.mailform.elements.author)!="undefined") {
1.5       www       324:           if (document.mailform.elements.author.checked) {
                    325:              rec=1;
                    326:           } 
                    327:         }
1.12      albertel  328:         if (typeof(document.mailform.elements.question)!="undefined") {
1.5       www       329:           if (document.mailform.elements.question.checked) {
                    330:              rec=1;
                    331:           } 
                    332:         }
1.12      albertel  333:         if (typeof(document.mailform.elements.course)!="undefined") {
1.5       www       334:           if (document.mailform.elements.course.checked) {
                    335:              rec=1;
                    336:           } 
                    337:         }
1.12      albertel  338:         if (typeof(document.mailform.elements.policy)!="undefined") {
1.5       www       339:           if (document.mailform.elements.policy.checked) {
                    340:              rec=1;
                    341:           } 
                    342:         }
1.12      albertel  343:         if (typeof(document.mailform.elements.discuss)!="undefined") {
1.10      www       344:           if (document.mailform.elements.discuss.checked) {
                    345:              rec=1;
                    346:           } 
                    347:         }
1.14      www       348:         if (typeof(document.mailform.elements.anondiscuss)!="undefined") {
                    349:           if (document.mailform.elements.anondiscuss.checked) {
                    350:              rec=1;
                    351:           } 
                    352:         }
1.5       www       353: 
                    354:         if (rec) {
                    355: 	    document.mailform.submit();
                    356:         } else {
                    357:             alert('Please check a feedback type.');
                    358: 	}
                    359:     }
1.63      albertel  360: //-->
1.5       www       361: </script>
1.1       www       362: </head>
1.29      www       363: $bodytag
1.51      albertel  364: <h2><tt>$title</tt></h2>
1.43      www       365: <form action="/adm/feedback" method="post" name="mailform"
                    366: enctype="multipart/form-data">
1.63      albertel  367: <input type="hidden" name="postdata" value="$feedurl" />
1.68      www       368: <input type="hidden" name="replydisc" value="$ENV{'form.replydisc'}" />
1.5       www       369: Please check at least one of the following feedback types:
1.63      albertel  370: $options<hr />
1.69      www       371: $quote
1.63      albertel  372: <p>My question/comment/feedback:</p>
                    373: <p>
1.47      bowersj2  374: $latexHelp
1.78    ! raeburn   375: Title: <input type="text" name="subject" size="30" value="$subject" /></p>
        !           376: <p>
1.63      albertel  377: <textarea name="comment" cols="60" rows="10" wrap="hard">
                    378: </textarea></p>
                    379: <p>
1.42      www       380: Attachment (128 KB max size): <input type="file" name="attachment" />
                    381: </p>
                    382: <p>
                    383: <input type="hidden" name="sendit" value="1" />
1.74      www       384: <input type="button" value="$send" onClick='gosubmit();' />
1.42      www       385: </p>
1.2       www       386: </form>
1.1       www       387: ENDDOCUMENT
1.33      www       388: $r->print(&generate_preview_button().'</body></html>');
1.6       albertel  389: }
                    390: 
                    391: sub fail_redirect {
                    392:   my ($r,$feedurl) = @_;
1.70      www       393:   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
1.6       albertel  394:   $r->print (<<ENDFAILREDIR);
1.72      albertel  395: <html>
1.5       www       396: <head><title>Feedback not sent</title>
1.63      albertel  397: <meta http-equiv="pragma" content="no-cache" />
                    398: <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
1.5       www       399: </head>
                    400: <body bgcolor="#FFFFFF">
1.63      albertel  401: <img align="right" src="/adm/lonIcons/lonlogos.gif" />
1.8       www       402: <b>Sorry, no recipients  ...</b>
1.5       www       403: </body>
                    404: </html>
                    405: ENDFAILREDIR
                    406: }
1.4       www       407: 
1.6       albertel  408: sub redirect_back {
1.32      albertel  409:   my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status) = @_;
1.70      www       410:   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
1.6       albertel  411:   $r->print (<<ENDREDIR);
1.72      albertel  412: <html>
1.3       www       413: <head>
                    414: <title>Feedback sent</title>
1.63      albertel  415: <meta http-equiv="pragma" content="no-cache" />
1.5       www       416: <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl">
1.2       www       417: </head>
1.49      www       418: <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>
1.63      albertel  419: <img align="right" src="/adm/lonIcons/lonlogos.gif" />
1.5       www       420: $typestyle
1.32      albertel  421: <b>Sent $sendsomething message(s), and $sendposts post(s).</b>
1.63      albertel  422: <font color="red">$status</font>
1.49      www       423: <form name="reldt" action="$feedurl" target="loncapaclient">
                    424: </form>
1.2       www       425: </body>
                    426: </html>
                    427: ENDREDIR
                    428: }
1.6       albertel  429: 
                    430: sub no_redirect_back {
                    431:   my ($r,$feedurl) = @_;
                    432:   $r->print (<<ENDNOREDIR);
1.72      albertel  433: <html>
1.2       www       434: <head><title>Feedback not sent</title>
1.63      albertel  435: <meta http-equiv="pragma" content="no-cache" />
1.7       albertel  436: ENDNOREDIR
                    437: 
1.8       www       438:   if ($feedurl!~/^\/adm\/feedback/) { 
1.7       albertel  439:     $r->print('<meta HTTP-EQUIV="Refresh" CONTENT="2; url='.$feedurl.'">');
                    440:   }
                    441:   
1.8       www       442:   $r->print (<<ENDNOREDIRTWO);
1.2       www       443: </head>
1.49      www       444: <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { self.close(); }'>
1.63      albertel  445: <img align="right" src="/adm/lonIcons/lonlogos.gif" />
1.8       www       446: <b>Sorry, no feedback possible on this resource  ...</b>
1.2       www       447: </body>
                    448: </html>
1.8       www       449: ENDNOREDIRTWO
1.2       www       450: }
1.6       albertel  451: 
                    452: sub screen_header {
1.65      www       453:     my ($feedurl) = @_;
                    454:     my $msgoptions='';
                    455:     my $discussoptions='';
                    456:     unless ($ENV{'form.replydisc'}) {
                    457: 	if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/)) {
                    458: 	    $msgoptions= 
                    459: 		'<p><input type="checkbox" name="author" /> '.
                    460: 		&mt('Feedback to resource author').'</p>';
                    461: 	}
                    462: 	if (&feedback_available(1)) {
                    463: 	    $msgoptions.=
                    464: 		'<br /><input type="checkbox" name="question" /> '.
                    465: 		&mt('Question about resource content');
                    466: 	}
                    467: 	if (&feedback_available(0,1)) {
                    468: 	    $msgoptions.=
                    469: 		'<br /><input type="checkbox" name="course" /> '.
                    470: 		&mt('Question/Comment/Feedback about course content');
                    471: 	}
                    472: 	if (&feedback_available(0,0,1)) {
                    473: 	    $msgoptions.=
                    474: 		'<br /><input type="checkbox" name="policy" /> '.
                    475: 		&mt('Question/Comment/Feedback about course policy');
                    476: 	}
                    477:     }
                    478:     if ($ENV{'request.course.id'}) {
                    479: 	if (&Apache::lonnet::allowed('pch',
                    480: 				     $ENV{'request.course.id'}.
                    481: 				     ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
1.74      www       482: 	    $discussoptions='<input type="checkbox" name="discuss" onClick="this.form.anondiscuss.checked=false;" '.
                    483: 		($ENV{'form.replydisc'}?' checked="1"':'').' /> '.
1.65      www       484: 		&mt('Contribution to course discussion of resource');
                    485: 	    $discussoptions.='<br /><input type="checkbox" name="anondiscuss" onClick="this.form.discuss.checked=false;" /> '.
                    486: 		&mt('Anonymous contribution to course discussion of resource').
                    487: 		' <i>('.&mt('name only visible to course faculty').')</i>';
1.20      www       488:       }
1.65      www       489:     }
1.74      www       490:     if ($msgoptions) { $msgoptions='<h2><img src="/adm/lonMisc/feedback.gif" />'.&mt('Sending Messages').'</h2>'.$msgoptions; }
1.65      www       491:     if ($discussoptions) { 
1.74      www       492: 	$discussoptions='<h2><img src="/adm/lonMisc/chat.gif" />'.&mt('Discussion Contributions').'</h2>'.$discussoptions; }
1.65      www       493:     return $msgoptions.$discussoptions;
1.6       albertel  494: }
                    495: 
                    496: sub resource_output {
                    497:   my ($feedurl) = @_;
1.46      albertel  498:   my $usersaw=&Apache::lonnet::ssi_body($feedurl);
1.6       albertel  499:   $usersaw=~s/\<body[^\>]*\>//gi;
                    500:   $usersaw=~s/\<\/body\>//gi;
                    501:   $usersaw=~s/\<html\>//gi;
                    502:   $usersaw=~s/\<\/html\>//gi;
                    503:   $usersaw=~s/\<head\>//gi;
                    504:   $usersaw=~s/\<\/head\>//gi;
                    505:   $usersaw=~s/action\s*\=/would_be_action\=/gi;
                    506:   return $usersaw;
                    507: }
                    508: 
                    509: sub clear_out_html {
1.39      www       510:   my ($message,$override)=@_;
1.37      albertel  511:   my $cid=$ENV{'request.course.id'};
1.39      www       512:   if (($ENV{"course.$cid.allow_limited_html_in_feedback"} =~ m/yes/i) ||
                    513:       ($override)) {
1.37      albertel  514:       # allows <B> <I> <P> <A> <LI> <OL> <UL> <EM> <BR> <TT> <STRONG> 
                    515:       # <BLOCKQUOTE> <DIV .*> <DIV> <IMG>
                    516:       my %html=(B=>1, I=>1, P=>1, A=>1, LI=>1, OL=>1, UL=>1, EM=>1,
1.61      www       517: 		BR=>1, TT=>1, STRONG=>1, BLOCKQUOTE=>1, DIV=>1, IMG=>1,
                    518:                 M=>1);
1.37      albertel  519: 
                    520:       $message =~ s/\<(\/?\s*(\w+)[^\>\<]*)/
1.48      albertel  521: 	  {($html{uc($2)}&&(length($1)<1000))?"\<$1":"\&lt;$1"}/ge;
1.37      albertel  522:       $message =~ s/(\<?\s*(\w+)[^\<\>]*)\>/
1.48      albertel  523: 	  {($html{uc($2)}&&(length($1)<1000))?"$1\>":"$1\&gt;"}/ge;
1.37      albertel  524:   } else {
                    525:       $message=~s/\</\&lt\;/g;
                    526:       $message=~s/\>/\&gt\;/g;
                    527:   }
1.6       albertel  528:   return $message;
                    529: }
                    530: 
                    531: sub assemble_email {
1.40      albertel  532:   my ($feedurl,$message,$prevattempts,$usersaw,$useranswer)=@_;
1.6       albertel  533:   my $email=<<"ENDEMAIL";
                    534: Refers to <a href="$feedurl">$feedurl</a>
                    535: 
                    536: $message
                    537: ENDEMAIL
                    538:     my $citations=<<"ENDCITE";
                    539: <h2>Previous attempts of student (if applicable)</h2>
                    540: $prevattempts
1.63      albertel  541: <br /><hr />
1.6       albertel  542: <h2>Original screen output (if applicable)</h2>
                    543: $usersaw
1.40      albertel  544: <h2>Correct Answer(s) (if applicable)</h2>
                    545: $useranswer
1.6       albertel  546: ENDCITE
                    547:   return ($email,$citations);
                    548: }
                    549: 
1.35      www       550: sub secapply {
                    551:     my $rec=shift;
1.36      www       552:     my $defaultflag=shift;
                    553:     $rec=~s/\s+//g;
                    554:     $rec=~s/\@/\:/g;
                    555:     my ($adr,$sections)=($rec=~/^([^\(]+)\(([^\)]+)\)/);
                    556:     if ($sections) {
                    557: 	foreach (split(/\;/,$sections)) {
                    558:             if (($_ eq $ENV{'request.course.sec'}) ||
                    559:                 ($defaultflag && ($_ eq '*'))) {
                    560:                 return $adr; 
                    561:             }
                    562:         }
                    563:     } else {
                    564:        return $rec;
                    565:     }
                    566:     return '';
1.35      www       567: }
                    568: 
1.6       albertel  569: sub decide_receiver {
1.36      www       570:   my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;
1.6       albertel  571:   my $typestyle='';
                    572:   my %to=();
1.36      www       573:   if ($ENV{'form.author'}||$author) {
1.8       www       574:     $typestyle.='Submitting as Author Feedback<br>';
1.6       albertel  575:     $feedurl=~/^\/res\/(\w+)\/(\w+)\//;
                    576:     $to{$2.':'.$1}=1;
                    577:   }
1.36      www       578:   if ($ENV{'form.question'}||$question) {
1.8       www       579:     $typestyle.='Submitting as Question<br>';
1.24      harris41  580:     foreach (split(/\,/,
                    581: 		   $ENV{'course.'.$ENV{'request.course.id'}.'.question.email'})
                    582: 	     ) {
1.36      www       583: 	my $rec=&secapply($_,$defaultflag);
                    584:         if ($rec) { $to{$rec}=1; }
1.24      harris41  585:     } 
1.6       albertel  586:   }
1.36      www       587:   if ($ENV{'form.course'}||$course) {
1.63      albertel  588:     $typestyle.='Submitting as Comment<br />';
1.24      harris41  589:     foreach (split(/\,/,
                    590: 		   $ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'})
                    591: 	     ) {
1.36      www       592: 	my $rec=&secapply($_,$defaultflag);
                    593:         if ($rec) { $to{$rec}=1; }
1.24      harris41  594:     } 
1.6       albertel  595:   }
1.36      www       596:   if ($ENV{'form.policy'}||$policy) {
1.63      albertel  597:     $typestyle.='Submitting as Policy Feedback<br />';
1.24      harris41  598:     foreach (split(/\,/,
                    599: 		   $ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'})
                    600: 	     ) {
1.36      www       601: 	my $rec=&secapply($_,$defaultflag);
                    602:         if ($rec) { $to{$rec}=1; }
1.24      harris41  603:     } 
1.6       albertel  604:   }
1.36      www       605:   if ((scalar(%to) eq '0') && (!$defaultflag)) {
                    606:      ($typestyle,%to)=
                    607: 	 &decide_receiver($feedurl,$author,$question,$course,$policy,1);
                    608:   }
1.6       albertel  609:   return ($typestyle,%to);
1.36      www       610: }
                    611: 
                    612: sub feedback_available {
                    613:     my ($question,$course,$policy)=@_;
                    614:     my ($typestyle,%to)=&decide_receiver('',0,$question,$course,$policy);
                    615:     return scalar(%to);
1.6       albertel  616: }
                    617: 
                    618: sub send_msg {
1.43      www       619:   my ($feedurl,$email,$citations,$attachmenturl,%to)=@_;
1.6       albertel  620:   my $status='';
                    621:   my $sendsomething=0;
1.24      harris41  622:   foreach (keys %to) {
1.6       albertel  623:     if ($_) {
1.22      www       624:       my $declutter=&Apache::lonnet::declutter($feedurl);
1.8       www       625:       unless (&Apache::lonmsg::user_normal_msg(split(/\:/,$_),
1.43      www       626:                'Feedback ['.$declutter.']',$email,$citations,$feedurl,
                    627:                 $attachmenturl)=~/ok/) {
1.63      albertel  628: 	$status.='<br />'.&mt('Error sending message to').' '.$_.'<br />';
1.6       albertel  629:       } else {
                    630: 	$sendsomething++;
                    631:       }
                    632:     }
1.24      harris41  633:   }
1.18      www       634: 
                    635:     my %record=&Apache::lonnet::restore('_feedback');
                    636:     my ($temp)=keys %record;
                    637:     unless ($temp=~/^error\:/) {
                    638:        my %newrecord=();
                    639:        $newrecord{'resource'}=$feedurl;
                    640:        $newrecord{'subnumber'}=$record{'subnumber'}+1;
                    641:        unless (&Apache::lonnet::cstore(\%newrecord,'_feedback') eq 'ok') {
1.63      albertel  642: 	   $status.='<br />'.&mt('Not registered').'<br />';
1.18      www       643:        }
                    644:     }
                    645:        
1.6       albertel  646:   return ($status,$sendsomething);
                    647: }
                    648: 
1.13      www       649: sub adddiscuss {
1.78    ! raeburn   650:     my ($symb,$email,$anon,$attachmenturl,$subject)=@_;
1.13      www       651:     my $status='';
1.23      www       652:     if (&Apache::lonnet::allowed('pch',$ENV{'request.course.id'}.
                    653:         ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
1.20      www       654: 
1.13      www       655:     my %contrib=('message'      => $email,
                    656:                  'sendername'   => $ENV{'user.name'},
1.26      www       657:                  'senderdomain' => $ENV{'user.domain'},
                    658:                  'screenname'   => $ENV{'environment.screenname'},
                    659:                  'plainname'    => $ENV{'environment.firstname'}.' '.
                    660: 		                   $ENV{'environment.middlename'}.' '.
                    661:                                    $ENV{'environment.lastname'}.' '.
1.42      www       662:                                    $ENV{'enrironment.generation'},
1.78    ! raeburn   663:                  'attachmenturl'=> $attachmenturl,
        !           664:                  'subject'      => $subject);
1.65      www       665:     if ($ENV{'form.replydisc'}) {
1.66      www       666: 	$contrib{'replyto'}=(split(/\:\:\:/,$ENV{'form.replydisc'}))[1];
1.65      www       667:     }
1.14      www       668:     if ($anon) {
                    669: 	$contrib{'anonymous'}='true';
                    670:     }
1.13      www       671:     if (($symb) && ($email)) {
1.14      www       672:        $status='Adding to class discussion'.($anon?' (anonymous)':'').': '.
1.13      www       673:         &Apache::lonnet::store(\%contrib,$symb,$ENV{'request.course.id'},
                    674:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
1.17      www       675: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
1.21      www       676:         my %storenewentry=($symb => time);
1.63      albertel  677:         $status.='<br />'.&mt('Updating discussion time').': '.
1.21      www       678:         &Apache::lonnet::put('discussiontimes',\%storenewentry,
                    679:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                    680: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
1.13      www       681:     }
1.17      www       682:     my %record=&Apache::lonnet::restore('_discussion');
                    683:     my ($temp)=keys %record;
                    684:     unless ($temp=~/^error\:/) {
                    685:        my %newrecord=();
                    686:        $newrecord{'resource'}=$symb;
                    687:        $newrecord{'subnumber'}=$record{'subnumber'}+1;
1.63      albertel  688:        $status.='<br />'.&mt('Registering').': '.
1.21      www       689:                &Apache::lonnet::cstore(\%newrecord,'_discussion');
1.20      www       690:     }
                    691:     } else {
                    692: 	$status.='Failed.';
1.17      www       693:     }
1.63      albertel  694:     return $status.'<br />';   
1.13      www       695: }
                    696: 
1.33      www       697: # ----------------------------------------------------------- Preview function
                    698: 
                    699: sub show_preview {
                    700:     my $r=shift;
                    701:     my $message=&clear_out_html($ENV{'form.comment'});
                    702:     $message=~s/\n/\<br \/\>/g;
                    703:     $message=&Apache::lontexconvert::msgtexconverted($message);
1.78    ! raeburn   704:     my $subject=&clear_out_html($ENV{'form.subject'});
        !           705:     $subject=~s/\n/\<br \/\>/g;
        !           706:     $subject=&Apache::lontexconvert::msgtexconverted($subject);
1.33      www       707:     $r->print('<table border="2"><tr><td>'.
1.78    ! raeburn   708:        '<b>Subject:</b> '.$subject.'<br /><br />'.
1.33      www       709:        $message.'</td></tr></table>');
                    710: }
                    711: 
                    712: sub generate_preview_button {
1.65      www       713:     my $pre=&mt("Show Preview");
1.33      www       714:     return(<<ENDPREVIEW);
                    715: <form name="preview" action="/adm/feedback?preview=1" method="post" target="preview">
1.78    ! raeburn   716: <input type="hidden" name="subject">
1.33      www       717: <input type="hidden" name="comment" />
1.65      www       718: <input type="button" value="$pre"
1.78    ! raeburn   719: onClick="this.form.comment.value=document.mailform.comment.value;this.form.subject.value=document.mailform.subject.value;this.form.submit();" />
1.33      www       720: </form>
                    721: ENDPREVIEW
                    722: }
1.71      www       723: 
1.6       albertel  724: sub handler {
                    725:   my $r = shift;
1.8       www       726:   if ($r->header_only) {
1.71      www       727:      &Apache::loncommon::content_type($r,'text/html');
1.8       www       728:      $r->send_http_header;
                    729:      return OK;
                    730:   }
1.15      www       731: 
                    732: # --------------------------- Get query string for limited number of parameters
                    733: 
1.27      stredwic  734:    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.78    ! raeburn   735: #         ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff']);
        !           736:          ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff','markread','markunread','storereads','onlyunread','allposts','chgreads']);
1.15      www       737: 
1.78    ! raeburn   738:   if (($ENV{'form.markread'}) || ($ENV{'form.markunread'})) {
        !           739: # ----------------------------------------------------------------- Modify read/unread for all
        !           740:       &Apache::loncommon::content_type($r,'text/html');
        !           741:       $r->send_http_header;
        !           742:       my $symb=$ENV{'form.markread'}?$ENV{'form.markread'}:$ENV{'form.markunread'};
        !           743:       my $ressymb = $symb;
        !           744:       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
        !           745:       $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
        !           746:       my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
        !           747:                           $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
        !           748:                           $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
        !           749:       my %readinghash = ();
        !           750:                                                                                  
        !           751:       if ($contrib{'version'}) {
        !           752:           for (my $id=1;$id<=$contrib{'version'};$id++) {
        !           753:               my $msgid = $id.':message';
        !           754:               if (defined($contrib{$msgid})) {
        !           755:                   if ($ENV{'form.markread'}) {
        !           756:                       $readinghash{$id} = 'read';
        !           757:                   } else {
        !           758:                        $readinghash{$id} = 'unread';
        !           759:                   }
        !           760:               }
        !           761:           }
        !           762:           if ($ENV{'form.allposts'}) {
        !           763:               $readinghash{'showonlyunread'} = 0;
        !           764:           } elsif ($ENV{'form.onlyunread'}) {
        !           765:               $readinghash{'showonlyunread'} = 1;
        !           766:           }
        !           767:           &Apache::lonnet::cstore(\%readinghash,$symb,$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'});
        !           768:       }
        !           769:                                                                                  
        !           770:       &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed reading status'),'0','0');
        !           771:       return OK;
        !           772:   } else {
        !           773:       my $symb = $ENV{'form.discsymb'};
        !           774:       my %readinghash = ();
        !           775:       my $chgcount = 0;
        !           776:       foreach my $key (keys %ENV) {
        !           777:           if ($key =~ m/^form\.postunread_(\d+)/) {
        !           778:               $readinghash{$1} = 'unread';
        !           779:               $chgcount ++;
        !           780:           } elsif ($key =~ m/^form\.postread_(\d+)/) {
        !           781:               $readinghash{$1} = 'read';
        !           782:               $chgcount ++;
        !           783:           }
        !           784:       }
        !           785:       if ($ENV{'form.allposts'}) {
        !           786:           $readinghash{'showonlyunread'} = 0;
        !           787:           $chgcount ++;
        !           788:       } elsif ($ENV{'form.onlyunread'}) {
        !           789:           $readinghash{'showonlyunread'} = 1;
        !           790:           $chgcount ++;
        !           791:       }
        !           792:                                                                                  
        !           793:       if ($chgcount > 0) {
        !           794:           &Apache::lonnet::cstore(\%readinghash,$symb,$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'});
        !           795:       }
        !           796:   }
        !           797: 
        !           798:   if ($ENV{'form.chgreads'}) {
        !           799:       &Apache::loncommon::content_type($r,'text/html');
        !           800:       $r->send_http_header;
        !           801:       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($ENV{'form.chgreads'});
        !           802:       &redirect_back($r,&Apache::lonnet::clutter($url),
        !           803:        &mt('Changed read status').'<br />','0','0');
        !           804:   } elsif (($ENV{'form.hide'}) || ($ENV{'form.unhide'})) {
1.15      www       805: # ----------------------------------------------------------------- Hide/unhide
1.71      www       806:     &Apache::loncommon::content_type($r,'text/html');
1.15      www       807:     $r->send_http_header;
                    808: 
                    809:     my $entry=$ENV{'form.hide'}?$ENV{'form.hide'}:$ENV{'form.unhide'};
                    810: 
                    811:     my ($symb,$idx)=split(/\:\:\:/,$entry);
1.52      www       812:     my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
1.15      www       813: 
                    814:     my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
                    815:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                    816: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
                    817: 
                    818:         
                    819:     my $currenthidden=$contrib{'hidden'};
                    820:     
                    821:     if ($ENV{'form.hide'}) {
                    822: 	$currenthidden.='.'.$idx.'.';
                    823:     } else {
                    824:         $currenthidden=~s/\.$idx\.//g;
                    825:     }
                    826:     my %newhash=('hidden' => $currenthidden);
1.38      www       827: 
                    828:     &Apache::lonnet::store(\%newhash,$symb,$ENV{'request.course.id'},
                    829:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                    830: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
                    831: 
                    832:     &redirect_back($r,&Apache::lonnet::clutter($url),
1.78    ! raeburn   833:        &mt('Changed read status').'<br />','0','0');
1.69      www       834:   } elsif (($ENV{'form.threadedon'}) || ($ENV{'form.threadedoff'})) {
1.72      albertel  835:       &Apache::loncommon::content_type($r,'text/html');
                    836:       $r->send_http_header;
1.69      www       837:       if ($ENV{'form.threadedon'}) {
                    838: 	  &Apache::lonnet::put('environment',{'threadeddiscussion' => 'on'});
                    839: 	  &Apache::lonnet::appenv('environment.threadeddiscussion' => 'on');
                    840:       } else {
                    841:  	  &Apache::lonnet::del('environment',['threadeddiscussion']);
                    842: 	  &Apache::lonnet::delenv('environment\.threadeddiscussion');
1.72      albertel  843:       }
1.69      www       844:       my $symb=$ENV{'form.threadedon'}?$ENV{'form.threadedon'}:$ENV{'form.threadedoff'};
                    845:       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
                    846:       &redirect_back($r,&Apache::lonnet::clutter($url),
                    847: 		     &mt('Changed discussion view mode').'<br />','0','0');
1.38      www       848:   } elsif ($ENV{'form.deldisc'}) {
                    849: # --------------------------------------------------------------- Hide for good
1.71      www       850:     &Apache::loncommon::content_type($r,'text/html');
1.38      www       851:     $r->send_http_header;
                    852: 
                    853:     my $entry=$ENV{'form.deldisc'};
                    854: 
                    855:     my ($symb,$idx)=split(/\:\:\:/,$entry);
1.52      www       856:     my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
1.38      www       857: 
                    858:     my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
                    859:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                    860: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
                    861: 
                    862:         
                    863:     my $currentdeleted=$contrib{'deleted'};
                    864:     
                    865:     $currentdeleted.='.'.$idx.'.';
                    866: 
                    867:     my %newhash=('deleted' => $currentdeleted);
1.15      www       868: 
                    869:     &Apache::lonnet::store(\%newhash,$symb,$ENV{'request.course.id'},
                    870:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                    871: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
                    872: 
1.30      www       873:     &redirect_back($r,&Apache::lonnet::clutter($url),
1.63      albertel  874:        &mt('Changed discussion status').'<br />','0','0');
1.33      www       875:   } elsif ($ENV{'form.preview'}) {
                    876: # -------------------------------------------------------- User wants a preview
1.76      albertel  877:       $r->content_type('text/html');
                    878:       $r->send_http_header;
1.33      www       879:       &show_preview($r);
1.15      www       880:   } else {
                    881: # ------------------------------------------------------------- Normal feedback
1.6       albertel  882:   my $feedurl=$ENV{'form.postdata'};
                    883:   $feedurl=~s/^http\:\/\///;
                    884:   $feedurl=~s/^$ENV{'SERVER_NAME'}//;
                    885:   $feedurl=~s/^$ENV{'HTTP_HOST'}//;
1.62      www       886:   $feedurl=~s/\?.+$//;
1.8       www       887: 
1.66      www       888:   my $symb;
                    889:   if ($ENV{'form.replydisc'}) {
                    890:       $symb=(split(/\:\:\:/,$ENV{'form.replydisc'}))[0];
                    891:       my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
                    892:       $feedurl=&Apache::lonnet::clutter($url);
                    893:   } else {
                    894:       $symb=&Apache::lonnet::symbread($feedurl);
                    895:   }
1.31      www       896:   unless ($symb) {
                    897:       $symb=$ENV{'form.symb'};
                    898:       if ($symb) {
1.52      www       899: 	  my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
1.31      www       900:           $feedurl=&Apache::lonnet::clutter($url);
                    901:       }
                    902:   }
1.8       www       903:   my $goahead=1;
                    904:   if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form)$/) {
                    905:       unless ($symb) { $goahead=0; }
                    906:   }
1.74      www       907:   # backward compatibility (bulltin boards used to be 'wrapped')
1.73      albertel  908:   if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
                    909:       $feedurl=~s|^/adm/wrapper||;
                    910:   }
1.8       www       911:   if ($goahead) {
                    912: # Go ahead with feedback, no ambiguous reference
1.71      www       913:     &Apache::loncommon::content_type($r,'text/html');
1.8       www       914:     $r->send_http_header;
1.6       albertel  915:   
1.8       www       916:     if (
1.7       albertel  917:       (
                    918:        ($feedurl=~m:^/res:) && ($feedurl!~m:^/res/adm:)
                    919:       ) 
                    920:       || 
                    921:       ($ENV{'request.course.id'} && ($feedurl!~m:^/adm:))
1.31      www       922:       ||
                    923:       ($ENV{'request.course.id'} && ($symb=~/^bulletin\_\_\_/))
1.7       albertel  924:      ) {
1.6       albertel  925: # --------------------------------------------------- Print login screen header
                    926:     unless ($ENV{'form.sendit'}) {
                    927:       my $options=&screen_header($feedurl);
                    928:       if ($options) {
                    929: 	&mail_screen($r,$feedurl,$options);
                    930:       } else {
                    931: 	&fail_redirect($r,$feedurl);
                    932:       }
                    933:     } else {
                    934:       
                    935: # Get previous user input
1.9       albertel  936:       my $prevattempts=&Apache::loncommon::get_previous_attempt(
1.11      albertel  937:             $symb,$ENV{'user.name'},$ENV{'user.domain'},
1.9       albertel  938:             $ENV{'request.course.id'});
1.6       albertel  939: 
                    940: # Get output from resource
                    941:       my $usersaw=&resource_output($feedurl);
                    942: 
1.50      albertel  943: # Get resource answer (need to allow student to view grades for this to work)
                    944:       &Apache::lonnet::appenv(('allowed.vgr'=>'F'));
1.40      albertel  945:       my $useranswer=&Apache::loncommon::get_student_answers(
                    946:                        $symb,$ENV{'user.name'},$ENV{'user.domain'},
                    947: 		       $ENV{'request.course.id'});
1.50      albertel  948:       &Apache::lonnet::delenv('allowed.vgr');
1.42      www       949: # Get attachments, if any, and not too large
                    950:       my $attachmenturl='';
                    951:       if ($ENV{'form.attachment.filename'}) {
                    952: 	  unless (length($ENV{'form.attachment'})>131072) {
1.43      www       953: 	      $attachmenturl=&Apache::lonnet::userfileupload('attachment');
1.42      www       954: 	  }
                    955:       }
1.6       albertel  956: # Filter HTML out of message (could be nasty)
1.39      www       957:       my $message=&clear_out_html($ENV{'form.comment'});
1.6       albertel  958: 
                    959: # Assemble email
1.8       www       960:       my ($email,$citations)=&assemble_email($feedurl,$message,$prevattempts,
1.40      albertel  961:           $usersaw,$useranswer);
                    962:  
1.6       albertel  963: # Who gets this?
                    964:       my ($typestyle,%to) = &decide_receiver($feedurl);
                    965: 
                    966: # Actually send mail
1.43      www       967:       my ($status,$numsent)=&send_msg($feedurl,$email,$citations,
                    968:           $attachmenturl,%to);
1.13      www       969: 
                    970: # Discussion? Store that.
                    971: 
1.32      albertel  972:       my $numpost=0;
1.13      www       973:       if ($ENV{'form.discuss'}) {
1.78    ! raeburn   974:           my $subject = &clear_out_html($ENV{'form.subject'});
        !           975: 	  $typestyle.=&adddiscuss($symb,$message,0,$attachmenturl,$subject);
1.32      albertel  976: 	  $numpost++;
1.13      www       977:       }
1.6       albertel  978: 
1.14      www       979:       if ($ENV{'form.anondiscuss'}) {
1.78    ! raeburn   980:           my $subject = &clear_out_html($ENV{'form.subject'});
        !           981: 	  $typestyle.=&adddiscuss($symb,$message,1,$attachmenturl,$subject);
1.32      albertel  982: 	  $numpost++;
1.14      www       983:       }
                    984: 
                    985: 
1.6       albertel  986: # Receipt screen and redirect back to where came from
1.32      albertel  987:       &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$status);
1.6       albertel  988: 
                    989:     }
1.8       www       990:    } else {
1.7       albertel  991: # Unable to give feedback
1.6       albertel  992:     &no_redirect_back($r,$feedurl);
1.8       www       993:    }
                    994:   } else {
                    995: # Ambiguous Problem Resource
1.60      albertel  996:       if ( &Apache::lonnet::mod_perl_version() == 2 ) {
1.53      albertel  997: 	  &Apache::lonnet::cleanenv();
1.58      albertel  998:       }
1.53      albertel  999:       $r->internal_redirect('/adm/ambiguous');
1.6       albertel 1000:   }
1.15      www      1001: }
1.6       albertel 1002:   return OK;
1.1       www      1003: } 
                   1004: 
                   1005: 1;
                   1006: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>