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

1.1       www         1: # The LearningOnline Network
                      2: # Feedback
                      3: #
1.93    ! albertel    4: # $Id: lonfeedback.pm,v 1.92 2004/06/04 19:27:33 albertel 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.86      www        37: use Apache::lonlocal; # must not have ()
                     38: use Apache::lonhtmlcommon();
1.54      www        39: 
1.92      albertel   40: sub discussion_open {
1.90      albertel   41:     my ($status)=@_;
1.92      albertel   42:     if (defined($status) &&
                     43: 	!($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
1.77      www        44: 	  || $status eq 'OPEN')) {
1.92      albertel   45: 	return 0;
1.75      albertel   46:     }
1.89      albertel   47:     my $close=&Apache::lonnet::EXT('resource.0.discussend');
                     48:     if (defined($close) && $close ne '' && $close < time) {
1.92      albertel   49: 	return 0;
1.89      albertel   50:     }
1.92      albertel   51:     return 1;
                     52: }
                     53: 
                     54: sub discussion_visible {
                     55:     my ($status)=@_;
                     56:     if (not &discussion_open($status)) {
                     57: 	my $hidden=&Apache::lonnet::EXT('resource.0.discusshide');
                     58: 	if (lc($hidden) eq 'yes' or $hidden eq '' or !defined($hidden))  {
                     59: 	    return 0;
                     60: 	}
                     61:     }
                     62:     return 1;
1.90      albertel   63: }
1.84      raeburn    64: 
1.90      albertel   65: sub list_discussion {
                     66:     my ($mode,$status,$symb)=@_;
                     67: 
1.92      albertel   68:     if (not &discussion_visible($status)) { return ''; }
1.84      raeburn    69:     my @bgcols = ("#cccccc","#eeeeee");
1.57      www        70:     my $discussiononly=0;
                     71:     if ($mode eq 'board') { $discussiononly=1; }
1.55      www        72:     unless ($ENV{'request.course.id'}) { return ''; }
                     73:     my $crs='/'.$ENV{'request.course.id'};
                     74:     if ($ENV{'request.course.sec'}) {
                     75: 	$crs.='_'.$ENV{'request.course.sec'};
                     76:     }                 
                     77:     $crs=~s/\_/\//g;
1.54      www        78:     unless ($symb) {
                     79: 	$symb=&Apache::lonnet::symbread();
                     80:     }
                     81:     unless ($symb) { return ''; }
1.78      raeburn    82: 
1.80      raeburn    83: # backward compatibility (bulletin boards used to be 'wrapped')
                     84:     my $ressymb=$symb;
                     85:     if ($mode eq 'board') {
                     86:         unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
                     87:             $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
                     88:         }
                     89:     }
                     90: 
                     91: # Get discussion display settings for this discussion
                     92:     my $lastkey = $ressymb.'_lastread';
                     93:     my $showkey = $ressymb.'_showonlyunread';
                     94:     my $visitkey = $ressymb.'_visit';
1.84      raeburn    95:     my $ondispkey = $ressymb.'_markondisp';
                     96:     my %dischash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$lastkey,$showkey,$visitkey,$ondispkey],$ENV{'user.domain'},$ENV{'user.name'});
                     97:     my %discinfo = ();
1.80      raeburn    98:     my $showonlyunread = 0;
1.84      raeburn    99:     my $markondisp = 0;
1.79      raeburn   100:     my $prevread = 0;
1.81      raeburn   101:     my $previous = 0;
1.80      raeburn   102:     my $visit = 0;
                    103:     my $newpostsflag = 0;
                    104: 
1.81      raeburn   105: # Retain identification of "NEW" posts identified in last display, if continuing 'previous' browsing of posts.
                    106:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous']);
                    107:     $previous = $ENV{'form.previous'};
1.80      raeburn   108:     if ($previous > 0) {
                    109:         $prevread = $previous;
                    110:     } elsif (defined($dischash{$lastkey})) {
1.84      raeburn   111:         unless ($dischash{$lastkey} eq '') {
                    112:             $prevread = $dischash{$lastkey};
                    113:         }
1.80      raeburn   114:     }
1.79      raeburn   115: 
1.84      raeburn   116: # Get discussion display default settings for user
                    117:     my %userenv = &Apache::lonnet::get('environment',['discdisplay','discmarkread'],$ENV{'user.domain'},$ENV{'user.name'});
1.83      raeburn   118:     my $discdisplay=$userenv{'discdisplay'};
                    119:     if ($discdisplay eq 'unread') {
                    120:         $showonlyunread = 1;
                    121:     }
1.84      raeburn   122:     my $discmarkread=$userenv{'discmarkread'};
                    123:     if ($discmarkread eq 'ondisp') {
                    124:         $markondisp = 1;
                    125:     }
                    126: 
                    127: # Override user's default if user specified display setting for this discussion
                    128:     if (defined($dischash{$ondispkey})) {
                    129:         $markondisp = $dischash{$ondispkey};
                    130:     }
                    131:     if ($markondisp) {
                    132:         $discinfo{$lastkey} = time;
                    133:     }
1.83      raeburn   134: 
1.80      raeburn   135:     if (defined($dischash{$showkey})) {
                    136:         $showonlyunread = $dischash{$showkey};
                    137:     }
                    138: 
                    139:     if (defined($dischash{$visitkey})) {
                    140:         $visit = $dischash{$visitkey};
1.78      raeburn   141:     }
1.80      raeburn   142:     $visit ++;
1.78      raeburn   143: 
1.54      www       144:     my $seeid=&Apache::lonnet::allowed('rin',$crs);
1.77      www       145:     my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
                    146: 	&& ($symb=~/\.(problem|exam|quiz|assess|survey|form)$/));
1.68      www       147:     my @discussionitems=();
1.73      albertel  148:     my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
1.54      www       149: 			  $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                    150: 			  $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
1.67      www       151:     my $visible=0;
1.68      www       152:     my @depth=();
                    153:     my @original=();
                    154:     my @index=();
                    155:     my @replies=();
                    156:     my %alldiscussion=();
1.80      raeburn   157:     my %notshown = ();
1.84      raeburn   158:     my %newitem = ();
1.68      www       159:     my $maxdepth=0;
                    160: 
1.69      www       161:     my $target='';
                    162:     unless ($ENV{'browser.interface'} eq 'textual' ||
                    163: 	    $ENV{'environment.remote'} eq 'off' ) {
                    164: 	$target='target="LONcom"';
                    165:     }
1.79      raeburn   166:     
                    167:     my $now = time;
1.80      raeburn   168:     $discinfo{$visitkey} = $visit;
                    169: 
                    170:     &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
1.79      raeburn   171: 
1.54      www       172:     if ($contrib{'version'}) {
1.84      raeburn   173:         my $oldest = $contrib{'1:timestamp'};
                    174:         if ($prevread eq '0') {
                    175:             $prevread = $oldest-1;
                    176:         }
1.64      www       177: 	for (my $id=1;$id<=$contrib{'version'};$id++) {
                    178: 	    my $idx=$id;
1.80      raeburn   179:             my $posttime = $contrib{$idx.':timestamp'};
1.84      raeburn   180:             if ($prevread <= $posttime) {
1.80      raeburn   181:                 $newpostsflag = 1;
                    182:             }
1.54      www       183: 	    my $hidden=($contrib{'hidden'}=~/\.$idx\./);
                    184: 	    my $deleted=($contrib{'deleted'}=~/\.$idx\./);
1.68      www       185: 	    my $origindex='0.';
1.69      www       186: 	    if (($contrib{$idx.':replyto'}) && ($ENV{'environment.threadeddiscussion'})) {
1.68      www       187: # this is a follow-up message
                    188: 		$original[$idx]=$original[$contrib{$idx.':replyto'}];
                    189: 		$depth[$idx]=$depth[$contrib{$idx.':replyto'}]+1;
                    190: 		$origindex=$index[$contrib{$idx.':replyto'}];
                    191: 		if ($depth[$idx]>$maxdepth) { $maxdepth=$depth[$idx]; }
                    192: 	    } else {
                    193: # this is an original message
                    194: 		$original[$idx]=0;
                    195: 		$depth[$idx]=0;
                    196: 	    }
                    197: 	    if ($replies[$depth[$idx]]) {
                    198: 		$replies[$depth[$idx]]++;
                    199: 	    } else {
                    200: 		$replies[$depth[$idx]]=1;
                    201: 	    }
1.54      www       202: 	    unless ((($hidden) && (!$seeid)) || ($deleted)) {
1.67      www       203: 		$visible++;
1.54      www       204: 		my $message=$contrib{$idx.':message'};
                    205: 		$message=~s/\n/\<br \/\>/g;
                    206: 		$message=&Apache::lontexconvert::msgtexconverted($message);
1.78      raeburn   207:                 my $subject=$contrib{$idx.':subject'};
                    208:                 if (defined($subject)) {
                    209:                     $subject=~s/\n/\<br \/\>/g;
                    210:                     $subject=&Apache::lontexconvert::msgtexconverted($subject);
                    211:                 }
1.54      www       212: 		if ($contrib{$idx.':attachmenturl'}) {
1.82      albertel  213: 		    my ($fname)
                    214:                         =($contrib{$idx.':attachmenturl'}=~m|/([^/]+)$|);
                    215: 		    &Apache::lonnet::allowuploaded('/adm/feedback',
                    216: 					   $contrib{$idx.':attachmenturl'});
                    217: 		    $message.='<p>'.&mt('Attachment').
                    218: 			': <a href="'.$contrib{$idx.':attachmenturl'}.'"><tt>'.
                    219: 			$fname.'</tt></a></p>';
1.54      www       220: 		}
                    221: 		if ($message) {
                    222: 		    if ($hidden) {
                    223: 			$message='<font color="#888888">'.$message.'</font>';
                    224: 		    }
                    225: 		    my $screenname=&Apache::loncommon::screenname(
                    226: 					    $contrib{$idx.':sendername'},
                    227: 					    $contrib{$idx.':senderdomain'});
                    228: 		    my $plainname=&Apache::loncommon::nickname(
                    229: 					    $contrib{$idx.':sendername'},
                    230: 					    $contrib{$idx.':senderdomain'});
                    231: 		    
1.62      www       232: 		    my $sender=&mt('Anonymous');
1.54      www       233: 		    if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {
                    234: 			$sender=&Apache::loncommon::aboutmewrapper(
                    235: 					 $plainname,
                    236: 					 $contrib{$idx.':sendername'},
                    237: 					 $contrib{$idx.':senderdomain'}).' ('.
                    238: 					 $contrib{$idx.':sendername'}.' at '.
                    239: 					 $contrib{$idx.':senderdomain'}.')';
                    240: 			if ($contrib{$idx.':anonymous'}) {
1.62      www       241: 			    $sender.=' ['.&mt('anonymous').'] '.
1.54      www       242: 				$screenname;
                    243: 			}
                    244: 			if ($seeid) {
                    245: 			    if ($hidden) {
                    246: 				$sender.=' <a href="/adm/feedback?unhide='.
1.80      raeburn   247: 				    $ressymb.':::'.$idx;
                    248:                                 if ($newpostsflag) {
                    249:                                     $sender .= '&previous='.$prevread;
                    250:                                 }
                    251:                                 $sender .= '">'.&mt('Make Visible').'</a>';
1.54      www       252: 			    } else {
                    253: 				$sender.=' <a href="/adm/feedback?hide='.
1.80      raeburn   254: 				    $ressymb.':::'.$idx;
                    255:                                 if ($newpostsflag) {
                    256:                                     $sender .= '&previous='.$prevread;
                    257:                                 }
                    258:                                 $sender .= '">'.&mt('Hide').'</a>';
1.54      www       259: 			    }                     
                    260: 			    $sender.=' <a href="/adm/feedback?deldisc='.
1.80      raeburn   261: 				$ressymb.':::'.$idx;
                    262:                                 if ($newpostsflag) {
                    263:                                     $sender .= '&previous='.$prevread;
                    264:                                 }
                    265:                                 $sender .= '">'.&mt('Delete').'</a>';
1.64      www       266: 			}
1.54      www       267: 		    } else {
                    268: 			if ($screenname) {
                    269: 			    $sender='<i>'.$screenname.'</i>';
                    270: 			}
1.77      www       271: 		    }
1.92      albertel  272: 		    if (&discussion_open($status) &&
1.90      albertel  273: 			&Apache::lonnet::allowed('pch',
1.77      www       274: 						 $ENV{'request.course.id'}.
                    275: 						 ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
                    276: 			$sender.=' <a href="/adm/feedback?replydisc='.
1.80      raeburn   277: 			    $ressymb.':::'.$idx;
                    278:                         if ($newpostsflag) {
                    279:                             $sender .= '&previous='.$prevread;
                    280:                         }
                    281:                         $sender .= '" '.$target.'>'.&mt('Reply').'</a>';
1.54      www       282: 		    }
                    283: 		    my $vgrlink;
                    284: 		    if ($viewgrades) {
                    285: 			$vgrlink=&Apache::loncommon::submlink('Submissions',
                    286:             $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$symb);
                    287: 		    }
1.68      www       288: #figure out at what position this needs to print
                    289: 		    my $thisindex=$idx;
1.69      www       290: 		    if ($ENV{'environment.threadeddiscussion'}) {
1.68      www       291: 			$thisindex=$origindex.substr('00'.$replies[$depth[$idx]],-2,2);	
                    292: 		    }
                    293: 		    $alldiscussion{$thisindex}=$idx;
                    294: 		    $index[$idx]=$thisindex;
1.79      raeburn   295:                     my $spansize = 2;
1.80      raeburn   296:                     if ($showonlyunread && $prevread > $posttime) {
                    297:                         $notshown{$idx} = 1;
1.78      raeburn   298:                     } else {
1.80      raeburn   299:                         if ($prevread > 0 && $prevread <= $posttime) {
1.84      raeburn   300:                             $newitem{$idx} = 1;
                    301:                             $discussionitems[$idx] .= '
                    302:                              <p><table border="0" width="100%">
                    303:                               <tr><td align="left"><font color="#FF0000"><b>NEW</b></font></td>';
                    304:                         } else {
                    305:                             $newitem{$idx} = 0;
                    306:                             $discussionitems[$idx] .= '
                    307:                              <p><table border="0" width="100%">
                    308:                               <tr><td align="left">&nbsp;</td>';
1.80      raeburn   309:                         }
                    310:                         $discussionitems[$idx] .= '<td align ="left">&nbsp;&nbsp;'.
                    311:                             '<b>'.$subject.'</b>&nbsp;&nbsp;'.
                    312:                             $sender.'</b> '.$vgrlink.' ('.
                    313:                             localtime($posttime).')</td></tr>'.
                    314:                             '</table><blockquote>'.$message.'</blockquote></p>';
1.78      raeburn   315:                     }
                    316:                 }
                    317:             }
1.54      www       318: 	}
1.64      www       319:     }
1.80      raeburn   320: 
1.67      www       321:     my $discussion='';
1.84      raeburn   322: 
                    323:     my $function = &Apache::loncommon::get_users_function();
                    324:     my $color = &Apache::loncommon::designparm($function.'.tabbg',
                    325:                                                     $ENV{'user.domain'});
                    326:     my %lt = &Apache::lonlocal::texthash(
                    327:         'cuse' => 'Current settings for this discussion',
                    328:         'allposts' => 'All posts',
                    329:         'unread' => 'New posts only',
                    330:         'ondisp' => 'Once displayed',
                    331:         'onmark' => 'Once marked read',
                    332:         'disa' => 'Posts to be displayed',
                    333:         'npce' => 'Posts cease to be marked "NEW"',
                    334:         'chgt' => 'Change to ',
                    335:     );
                    336: 
                    337:     my $currdisp = $lt{'allposts'};
                    338:     my $currmark = $lt{'onmark'};
                    339:     my $dispchange = $lt{'unread'};
                    340:     my $markchange = $lt{'ondisp'};
                    341:     my $displink = '/adm/feedback?onlyunread='.$ressymb;
                    342:     my $marklink = '/adm/feedback?markondisp='.$ressymb;
                    343: 
                    344:     if ($markondisp) {
                    345:         $currmark = $lt{'ondisp'};
                    346:         $markchange = $lt{'onmark'};
                    347:         $marklink = '/adm/feedback?markonread='.$ressymb;
                    348:         if ($newpostsflag) {
                    349:             $marklink .= '&previous='.$prevread;
                    350:         }
                    351:     }
                    352: 
                    353:     if ($showonlyunread) {
                    354:         $currdisp = $lt{'unread'};
                    355:         $dispchange = $lt{'allposts'};
                    356:         $displink = '/adm/feedback?allposts='.$ressymb;
                    357:     }
                    358: 
                    359:     if ($newpostsflag) {
                    360:         $displink .= '&previous='.$prevread;
                    361:     }
                    362: 
1.67      www       363:     if ($visible) {
1.80      raeburn   364: # Print the discusssion
1.67      www       365: 	$discussion.='<table bgcolor="#AAAAAA" cellpadding="2" cellspacing="2" border="0">';
1.84      raeburn   366: 	my $colspan=$maxdepth+1;
                    367:         $discussion .= '<tr bgcolor="#FFFFFF"><td colspan="'.$colspan.'" valign="top">'.
                    368:         '<table border="0" bgcolor="#FFFFFF" width="100%" cellspacing="2" cellpadding="2">'.
                    369:         '<tr><td align="left"><b>'.$lt{'cuse'}.'</b></td><td>&nbsp;&nbsp;&nbsp;&nbsp;</td><td align="right"><b>'.$lt{'chgt'}.'</b></td></tr>'.
                    370:         '<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>'.
                    371:         '<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>'.
                    372:         '</table></td></tr>'.
                    373:         '<tr><td bgcolor="#DDDDBB" colspan="'.$colspan.'">'.
                    374:         '<table border="0" width="100%" bgcolor="#DDDDBB"><tr>';
                    375:         if ($visible>2) {
                    376: 	    $discussion.='<td align="left">'.
                    377:             '<a href="/adm/feedback?threadedon='.$ressymb;
                    378:             if ($newpostsflag) {
                    379:                 $discussion .= '&previous='.$prevread;
                    380:             }
                    381:             $discussion .='">'.&mt('Threaded View').'</a>&nbsp;&nbsp;'.
                    382:             '<a href="/adm/feedback?threadedoff='.$ressymb;
                    383:             if ($newpostsflag) {
                    384:                 $discussion .= '&previous='.$prevread;
                    385:             }
                    386:             $discussion .='">'.&mt('Chronological View').'</a>&nbsp;&nbsp;</td>';
                    387: 	} 
                    388:         if ($newpostsflag) {
                    389:             if (!$markondisp) {
                    390:                 $discussion .='<td align="right"><a href="/adm/feedback?markread='.$ressymb.'">'.&mt('Mark new posts as read').'</a>&nbsp;&nbsp;';
1.78      raeburn   391:             } else {
1.84      raeburn   392:                 $discussion .= '<td>&nbsp;</td>';
1.78      raeburn   393:             }
1.84      raeburn   394:         } else {
                    395:             $discussion .= '<td>&nbsp;</td>';
                    396:         }
                    397:         $discussion .= '</tr></table></td></tr>';
                    398: 
1.80      raeburn   399:         my $numhidden = keys %notshown;
                    400:         if ($numhidden > 0) {
                    401:             my $colspan = $maxdepth+1;
                    402:             $discussion.="\n".'<tr><td bgcolor="#CCCCCC" colspan="'.$colspan.'">'.
                    403:                          '<a href="/adm/feedback?allposts='.$ressymb;
                    404:             if ($newpostsflag) {
                    405:                 $discussion .= '&previous='.$prevread;
                    406:             }
                    407:             $discussion .= '">'.&mt('Show all posts').'</a> '.&mt('to display').' '.
                    408:                          $numhidden.' '.&mt('previously viewed posts').
                    409:                          '<br/></td></tr>';
                    410:         }
1.68      www       411: 	foreach (sort { $a <=> $b } keys %alldiscussion) {
1.80      raeburn   412:             unless ($notshown{$alldiscussion{$_}} eq '1') {
                    413: 	        $discussion.="\n<tr>";
                    414: 	        my $thisdepth=$depth[$alldiscussion{$_}];
                    415: 	        for (1..$thisdepth) {
                    416: 		    $discussion.='<td>&nbsp;&nbsp;&nbsp;</td>';
                    417: 	        }
                    418: 	        my $colspan=$maxdepth-$thisdepth+1;
1.84      raeburn   419:                 $discussion.='<td  bgcolor="'.$bgcols[$newitem{$alldiscussion{$_}}].'" colspan="'.$colspan.'">'.
1.80      raeburn   420:                              $discussionitems[$alldiscussion{$_}].
                    421: 	                     '</td></tr>';
1.69      www       422: 	    }
1.80      raeburn   423:         }
                    424:         $discussion.='</table><br /><br />';
1.54      www       425:     }
                    426:     if ($discussiononly) {
                    427: 	$discussion.=(<<ENDDISCUSS);
                    428: <form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data">
                    429: <input type="submit" name="discuss" value="Post Discussion" />
                    430: <input type="submit" name="anondiscuss" value="Post Anonymous Discussion" />
1.73      albertel  431: <input type="hidden" name="symb" value="$ressymb" />
1.54      www       432: <input type="hidden" name="sendit" value="true" />
                    433: <br />
                    434: <font size="1">Note: in anonymous discussion, your name is visible only to
                    435: course faculty</font><br />
1.78      raeburn   436: <b>Title:</b>&nbsp;<input type="text" name="subject" value="" size="30" /><br /><br />
1.88      www       437: <textarea name="comment" cols="60" rows="12" wrap="hard"></textarea>
1.54      www       438: <p>
                    439: Attachment (128 KB max size): <input type="file" name="attachment" />
                    440: </p>
                    441: </form>
                    442: ENDDISCUSS
                    443:       $discussion.=&generate_preview_button();
1.74      www       444:     } else {
1.92      albertel  445: 	if (&discussion_open($status) &&
1.90      albertel  446: 	    &Apache::lonnet::allowed('pch',
1.74      www       447: 				   $ENV{'request.course.id'}.
                    448: 	($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
                    449: 			    $discussion.='<table bgcolor="#BBBBBB"><tr><td><a href="/adm/feedback?replydisc='.
                    450: 				$symb.':::" '.$target.'>'.
                    451: 				'<img src="/adm/lonMisc/chat.gif" border="0" />'.
                    452: 				&mt('Post Discussion').'</a></td></tr></table>';
                    453: 			}
                    454:     }
1.54      www       455:    return $discussion;
                    456: }
1.1       www       457: 
1.6       albertel  458: sub mail_screen {
                    459:   my ($r,$feedurl,$options) = @_;
1.45      www       460:   my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion',
                    461:                                           '','onLoad="window.focus();"');
1.51      albertel  462:   my $title=&Apache::lonnet::gettitle($feedurl);
                    463:   if (!$title) { $title = $feedurl; }
1.69      www       464:   my $quote='';
1.78      raeburn   465:   my $subject = '';
1.80      raeburn   466:   my $prevtag = '';
1.69      www       467:   if ($ENV{'form.replydisc'}) {
                    468:       my ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'});
                    469:       my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
                    470: 					   $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                    471: 					   $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
1.80      raeburn   472:       unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) {
1.69      www       473: 	  my $message=$contrib{$idx.':message'};
                    474: 	  $message=~s/\n/\<br \/\>/g;
                    475: 	  $quote='<blockquote>'.&Apache::lontexconvert::msgtexconverted($message).'</blockquote>';
1.79      raeburn   476:           if ($idx > 0) {
                    477:               $subject = 'Re: '.$contrib{$idx.':subject'};
                    478:           }
1.69      www       479:       }
1.80      raeburn   480:       if ($ENV{'form.previous'}) {
                    481:           $prevtag = '<input type="hidden" name="previous" value="'.$ENV{'form.previous'}.'" />';
                    482:       }
1.69      www       483:   }
1.85      www       484:   my $latexHelp=&Apache::loncommon::helpLatexCheatsheet();
1.86      www       485:   my $htmlheader=&Apache::lonhtmlcommon::htmlareaheaders();
1.74      www       486:   my $send=&mt('Send');
1.6       albertel  487:   $r->print(<<ENDDOCUMENT);
1.1       www       488: <html>
                    489: <head>
                    490: <title>The LearningOnline Network with CAPA</title>
1.7       albertel  491: <meta http-equiv="pragma" content="no-cache"></meta>
1.85      www       492: $htmlheader
1.63      albertel  493: <script type="text/javascript">
                    494: //<!--
1.5       www       495:     function gosubmit() {
                    496:         var rec=0;
1.12      albertel  497:         if (typeof(document.mailform.elements.author)!="undefined") {
1.5       www       498:           if (document.mailform.elements.author.checked) {
                    499:              rec=1;
                    500:           } 
                    501:         }
1.12      albertel  502:         if (typeof(document.mailform.elements.question)!="undefined") {
1.5       www       503:           if (document.mailform.elements.question.checked) {
                    504:              rec=1;
                    505:           } 
                    506:         }
1.12      albertel  507:         if (typeof(document.mailform.elements.course)!="undefined") {
1.5       www       508:           if (document.mailform.elements.course.checked) {
                    509:              rec=1;
                    510:           } 
                    511:         }
1.12      albertel  512:         if (typeof(document.mailform.elements.policy)!="undefined") {
1.5       www       513:           if (document.mailform.elements.policy.checked) {
                    514:              rec=1;
                    515:           } 
                    516:         }
1.12      albertel  517:         if (typeof(document.mailform.elements.discuss)!="undefined") {
1.10      www       518:           if (document.mailform.elements.discuss.checked) {
                    519:              rec=1;
                    520:           } 
                    521:         }
1.14      www       522:         if (typeof(document.mailform.elements.anondiscuss)!="undefined") {
                    523:           if (document.mailform.elements.anondiscuss.checked) {
                    524:              rec=1;
                    525:           } 
                    526:         }
1.5       www       527: 
                    528:         if (rec) {
1.86      www       529: 	    document.mailform.onsubmit();
1.5       www       530: 	    document.mailform.submit();
                    531:         } else {
                    532:             alert('Please check a feedback type.');
                    533: 	}
                    534:     }
1.63      albertel  535: //-->
1.5       www       536: </script>
1.1       www       537: </head>
1.29      www       538: $bodytag
1.51      albertel  539: <h2><tt>$title</tt></h2>
1.43      www       540: <form action="/adm/feedback" method="post" name="mailform"
                    541: enctype="multipart/form-data">
1.80      raeburn   542: $prevtag
1.63      albertel  543: <input type="hidden" name="postdata" value="$feedurl" />
1.68      www       544: <input type="hidden" name="replydisc" value="$ENV{'form.replydisc'}" />
1.5       www       545: Please check at least one of the following feedback types:
1.63      albertel  546: $options<hr />
1.69      www       547: $quote
1.63      albertel  548: <p>My question/comment/feedback:</p>
                    549: <p>
1.47      bowersj2  550: $latexHelp
1.78      raeburn   551: Title: <input type="text" name="subject" size="30" value="$subject" /></p>
                    552: <p>
1.63      albertel  553: <textarea name="comment" cols="60" rows="10" wrap="hard">
                    554: </textarea></p>
                    555: <p>
1.42      www       556: Attachment (128 KB max size): <input type="file" name="attachment" />
                    557: </p>
                    558: <p>
                    559: <input type="hidden" name="sendit" value="1" />
1.74      www       560: <input type="button" value="$send" onClick='gosubmit();' />
1.42      www       561: </p>
1.2       www       562: </form>
1.1       www       563: ENDDOCUMENT
1.85      www       564: $r->print(&generate_preview_button().
                    565: &Apache::lonhtmlcommon::htmlareaactive().
                    566: '</body></html>');
1.6       albertel  567: }
                    568: 
                    569: sub fail_redirect {
                    570:   my ($r,$feedurl) = @_;
1.70      www       571:   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
1.6       albertel  572:   $r->print (<<ENDFAILREDIR);
1.72      albertel  573: <html>
1.5       www       574: <head><title>Feedback not sent</title>
1.63      albertel  575: <meta http-equiv="pragma" content="no-cache" />
                    576: <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
1.5       www       577: </head>
                    578: <body bgcolor="#FFFFFF">
1.63      albertel  579: <img align="right" src="/adm/lonIcons/lonlogos.gif" />
1.8       www       580: <b>Sorry, no recipients  ...</b>
1.5       www       581: </body>
                    582: </html>
                    583: ENDFAILREDIR
                    584: }
1.4       www       585: 
1.6       albertel  586: sub redirect_back {
1.80      raeburn   587:   my ($r,$feedurl,$typestyle,$sendsomething,$sendposts,$status,$previous) = @_;
                    588:   my $prevtag = '';
                    589:   my $qrystr = '';
1.70      www       590:   if ($feedurl=~/^\/adm\//) { $feedurl.='?register=1' };
1.80      raeburn   591:   if ($previous > 0) {
                    592:       $qrystr = 'previous='.$previous;
                    593:       if ($feedurl =~ /\?register=1/) {
                    594:           $feedurl .= '&'.$qrystr;
                    595:       } else {
                    596:           $feedurl .= '?'.$qrystr;
                    597:       }
                    598:       $prevtag = '<input type="hidden" name="previous" value="'.$previous.'" />';
                    599:   }
1.6       albertel  600:   $r->print (<<ENDREDIR);
1.72      albertel  601: <html>
1.3       www       602: <head>
                    603: <title>Feedback sent</title>
1.63      albertel  604: <meta http-equiv="pragma" content="no-cache" />
1.80      raeburn   605: <meta HTTP-EQUIV="Refresh" CONTENT="2; url=$feedurl" />
1.2       www       606: </head>
1.49      www       607: <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { this.document.reldt.submit(); self.close(); }'>
1.63      albertel  608: <img align="right" src="/adm/lonIcons/lonlogos.gif" />
1.5       www       609: $typestyle
1.32      albertel  610: <b>Sent $sendsomething message(s), and $sendposts post(s).</b>
1.63      albertel  611: <font color="red">$status</font>
1.49      www       612: <form name="reldt" action="$feedurl" target="loncapaclient">
1.80      raeburn   613: $prevtag
1.49      www       614: </form>
1.2       www       615: </body>
                    616: </html>
                    617: ENDREDIR
                    618: }
1.6       albertel  619: 
                    620: sub no_redirect_back {
                    621:   my ($r,$feedurl) = @_;
                    622:   $r->print (<<ENDNOREDIR);
1.72      albertel  623: <html>
1.2       www       624: <head><title>Feedback not sent</title>
1.63      albertel  625: <meta http-equiv="pragma" content="no-cache" />
1.7       albertel  626: ENDNOREDIR
                    627: 
1.8       www       628:   if ($feedurl!~/^\/adm\/feedback/) { 
1.7       albertel  629:     $r->print('<meta HTTP-EQUIV="Refresh" CONTENT="2; url='.$feedurl.'">');
                    630:   }
                    631:   
1.8       www       632:   $r->print (<<ENDNOREDIRTWO);
1.2       www       633: </head>
1.49      www       634: <body bgcolor="#FFFFFF" onLoad='if (window.name!="loncapaclient") { self.close(); }'>
1.63      albertel  635: <img align="right" src="/adm/lonIcons/lonlogos.gif" />
1.8       www       636: <b>Sorry, no feedback possible on this resource  ...</b>
1.2       www       637: </body>
                    638: </html>
1.8       www       639: ENDNOREDIRTWO
1.2       www       640: }
1.6       albertel  641: 
                    642: sub screen_header {
1.65      www       643:     my ($feedurl) = @_;
                    644:     my $msgoptions='';
                    645:     my $discussoptions='';
                    646:     unless ($ENV{'form.replydisc'}) {
                    647: 	if (($feedurl=~/^\/res\//) && ($feedurl!~/^\/res\/adm/)) {
                    648: 	    $msgoptions= 
                    649: 		'<p><input type="checkbox" name="author" /> '.
                    650: 		&mt('Feedback to resource author').'</p>';
                    651: 	}
                    652: 	if (&feedback_available(1)) {
                    653: 	    $msgoptions.=
                    654: 		'<br /><input type="checkbox" name="question" /> '.
                    655: 		&mt('Question about resource content');
                    656: 	}
                    657: 	if (&feedback_available(0,1)) {
                    658: 	    $msgoptions.=
                    659: 		'<br /><input type="checkbox" name="course" /> '.
                    660: 		&mt('Question/Comment/Feedback about course content');
                    661: 	}
                    662: 	if (&feedback_available(0,0,1)) {
                    663: 	    $msgoptions.=
                    664: 		'<br /><input type="checkbox" name="policy" /> '.
                    665: 		&mt('Question/Comment/Feedback about course policy');
                    666: 	}
                    667:     }
                    668:     if ($ENV{'request.course.id'}) {
1.92      albertel  669: 	if (&discussion_open() &&
1.90      albertel  670: 	    &Apache::lonnet::allowed('pch',
1.65      www       671: 				     $ENV{'request.course.id'}.
                    672: 				     ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
1.74      www       673: 	    $discussoptions='<input type="checkbox" name="discuss" onClick="this.form.anondiscuss.checked=false;" '.
                    674: 		($ENV{'form.replydisc'}?' checked="1"':'').' /> '.
1.65      www       675: 		&mt('Contribution to course discussion of resource');
                    676: 	    $discussoptions.='<br /><input type="checkbox" name="anondiscuss" onClick="this.form.discuss.checked=false;" /> '.
                    677: 		&mt('Anonymous contribution to course discussion of resource').
                    678: 		' <i>('.&mt('name only visible to course faculty').')</i>';
1.20      www       679:       }
1.65      www       680:     }
1.74      www       681:     if ($msgoptions) { $msgoptions='<h2><img src="/adm/lonMisc/feedback.gif" />'.&mt('Sending Messages').'</h2>'.$msgoptions; }
1.65      www       682:     if ($discussoptions) { 
1.74      www       683: 	$discussoptions='<h2><img src="/adm/lonMisc/chat.gif" />'.&mt('Discussion Contributions').'</h2>'.$discussoptions; }
1.65      www       684:     return $msgoptions.$discussoptions;
1.6       albertel  685: }
                    686: 
                    687: sub resource_output {
                    688:   my ($feedurl) = @_;
1.46      albertel  689:   my $usersaw=&Apache::lonnet::ssi_body($feedurl);
1.6       albertel  690:   $usersaw=~s/\<body[^\>]*\>//gi;
                    691:   $usersaw=~s/\<\/body\>//gi;
                    692:   $usersaw=~s/\<html\>//gi;
                    693:   $usersaw=~s/\<\/html\>//gi;
                    694:   $usersaw=~s/\<head\>//gi;
                    695:   $usersaw=~s/\<\/head\>//gi;
                    696:   $usersaw=~s/action\s*\=/would_be_action\=/gi;
                    697:   return $usersaw;
                    698: }
                    699: 
                    700: sub clear_out_html {
1.39      www       701:   my ($message,$override)=@_;
1.88      www       702:   unless (&Apache::lonhtmlcommon::htmlareablocked()) { return $message; }
1.37      albertel  703:   my $cid=$ENV{'request.course.id'};
1.39      www       704:   if (($ENV{"course.$cid.allow_limited_html_in_feedback"} =~ m/yes/i) ||
                    705:       ($override)) {
1.37      albertel  706:       # allows <B> <I> <P> <A> <LI> <OL> <UL> <EM> <BR> <TT> <STRONG> 
1.88      www       707:       # <BLOCKQUOTE> <DIV .*> <DIV> <IMG> <M> <SPAN> <H1> <H2> <H3> <H4> <SUB>
                    708:       # <SUP>
1.37      albertel  709:       my %html=(B=>1, I=>1, P=>1, A=>1, LI=>1, OL=>1, UL=>1, EM=>1,
1.61      www       710: 		BR=>1, TT=>1, STRONG=>1, BLOCKQUOTE=>1, DIV=>1, IMG=>1,
1.88      www       711:                 M=>1, SUB=>1, SUP=>1, SPAN=>1, 
                    712: 		H1=>1, H2=>1, H3=>1, H4=>1, H5=>1);
1.37      albertel  713: 
                    714:       $message =~ s/\<(\/?\s*(\w+)[^\>\<]*)/
1.48      albertel  715: 	  {($html{uc($2)}&&(length($1)<1000))?"\<$1":"\&lt;$1"}/ge;
1.37      albertel  716:       $message =~ s/(\<?\s*(\w+)[^\<\>]*)\>/
1.48      albertel  717: 	  {($html{uc($2)}&&(length($1)<1000))?"$1\>":"$1\&gt;"}/ge;
1.37      albertel  718:   } else {
                    719:       $message=~s/\</\&lt\;/g;
                    720:       $message=~s/\>/\&gt\;/g;
                    721:   }
1.6       albertel  722:   return $message;
                    723: }
                    724: 
                    725: sub assemble_email {
1.40      albertel  726:   my ($feedurl,$message,$prevattempts,$usersaw,$useranswer)=@_;
1.6       albertel  727:   my $email=<<"ENDEMAIL";
                    728: Refers to <a href="$feedurl">$feedurl</a>
                    729: 
                    730: $message
                    731: ENDEMAIL
                    732:     my $citations=<<"ENDCITE";
                    733: <h2>Previous attempts of student (if applicable)</h2>
                    734: $prevattempts
1.63      albertel  735: <br /><hr />
1.6       albertel  736: <h2>Original screen output (if applicable)</h2>
                    737: $usersaw
1.40      albertel  738: <h2>Correct Answer(s) (if applicable)</h2>
                    739: $useranswer
1.6       albertel  740: ENDCITE
                    741:   return ($email,$citations);
                    742: }
                    743: 
1.35      www       744: sub secapply {
                    745:     my $rec=shift;
1.36      www       746:     my $defaultflag=shift;
                    747:     $rec=~s/\s+//g;
                    748:     $rec=~s/\@/\:/g;
                    749:     my ($adr,$sections)=($rec=~/^([^\(]+)\(([^\)]+)\)/);
                    750:     if ($sections) {
                    751: 	foreach (split(/\;/,$sections)) {
                    752:             if (($_ eq $ENV{'request.course.sec'}) ||
                    753:                 ($defaultflag && ($_ eq '*'))) {
                    754:                 return $adr; 
                    755:             }
                    756:         }
                    757:     } else {
                    758:        return $rec;
                    759:     }
                    760:     return '';
1.35      www       761: }
                    762: 
1.6       albertel  763: sub decide_receiver {
1.36      www       764:   my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;
1.6       albertel  765:   my $typestyle='';
                    766:   my %to=();
1.36      www       767:   if ($ENV{'form.author'}||$author) {
1.8       www       768:     $typestyle.='Submitting as Author Feedback<br>';
1.6       albertel  769:     $feedurl=~/^\/res\/(\w+)\/(\w+)\//;
                    770:     $to{$2.':'.$1}=1;
                    771:   }
1.36      www       772:   if ($ENV{'form.question'}||$question) {
1.8       www       773:     $typestyle.='Submitting as Question<br>';
1.24      harris41  774:     foreach (split(/\,/,
                    775: 		   $ENV{'course.'.$ENV{'request.course.id'}.'.question.email'})
                    776: 	     ) {
1.36      www       777: 	my $rec=&secapply($_,$defaultflag);
                    778:         if ($rec) { $to{$rec}=1; }
1.24      harris41  779:     } 
1.6       albertel  780:   }
1.36      www       781:   if ($ENV{'form.course'}||$course) {
1.63      albertel  782:     $typestyle.='Submitting as Comment<br />';
1.24      harris41  783:     foreach (split(/\,/,
                    784: 		   $ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'})
                    785: 	     ) {
1.36      www       786: 	my $rec=&secapply($_,$defaultflag);
                    787:         if ($rec) { $to{$rec}=1; }
1.24      harris41  788:     } 
1.6       albertel  789:   }
1.36      www       790:   if ($ENV{'form.policy'}||$policy) {
1.63      albertel  791:     $typestyle.='Submitting as Policy Feedback<br />';
1.24      harris41  792:     foreach (split(/\,/,
                    793: 		   $ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'})
                    794: 	     ) {
1.36      www       795: 	my $rec=&secapply($_,$defaultflag);
                    796:         if ($rec) { $to{$rec}=1; }
1.24      harris41  797:     } 
1.6       albertel  798:   }
1.36      www       799:   if ((scalar(%to) eq '0') && (!$defaultflag)) {
                    800:      ($typestyle,%to)=
                    801: 	 &decide_receiver($feedurl,$author,$question,$course,$policy,1);
                    802:   }
1.6       albertel  803:   return ($typestyle,%to);
1.36      www       804: }
                    805: 
                    806: sub feedback_available {
                    807:     my ($question,$course,$policy)=@_;
                    808:     my ($typestyle,%to)=&decide_receiver('',0,$question,$course,$policy);
                    809:     return scalar(%to);
1.6       albertel  810: }
                    811: 
                    812: sub send_msg {
1.43      www       813:   my ($feedurl,$email,$citations,$attachmenturl,%to)=@_;
1.6       albertel  814:   my $status='';
                    815:   my $sendsomething=0;
1.24      harris41  816:   foreach (keys %to) {
1.6       albertel  817:     if ($_) {
1.22      www       818:       my $declutter=&Apache::lonnet::declutter($feedurl);
1.8       www       819:       unless (&Apache::lonmsg::user_normal_msg(split(/\:/,$_),
1.43      www       820:                'Feedback ['.$declutter.']',$email,$citations,$feedurl,
                    821:                 $attachmenturl)=~/ok/) {
1.63      albertel  822: 	$status.='<br />'.&mt('Error sending message to').' '.$_.'<br />';
1.6       albertel  823:       } else {
                    824: 	$sendsomething++;
                    825:       }
                    826:     }
1.24      harris41  827:   }
1.18      www       828: 
                    829:     my %record=&Apache::lonnet::restore('_feedback');
                    830:     my ($temp)=keys %record;
                    831:     unless ($temp=~/^error\:/) {
                    832:        my %newrecord=();
                    833:        $newrecord{'resource'}=$feedurl;
                    834:        $newrecord{'subnumber'}=$record{'subnumber'}+1;
                    835:        unless (&Apache::lonnet::cstore(\%newrecord,'_feedback') eq 'ok') {
1.63      albertel  836: 	   $status.='<br />'.&mt('Not registered').'<br />';
1.18      www       837:        }
                    838:     }
                    839:        
1.6       albertel  840:   return ($status,$sendsomething);
                    841: }
                    842: 
1.13      www       843: sub adddiscuss {
1.78      raeburn   844:     my ($symb,$email,$anon,$attachmenturl,$subject)=@_;
1.13      www       845:     my $status='';
1.92      albertel  846:     if (&discussion_open() &&
1.90      albertel  847: 	&Apache::lonnet::allowed('pch',$ENV{'request.course.id'}.
1.23      www       848:         ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
1.20      www       849: 
1.13      www       850:     my %contrib=('message'      => $email,
                    851:                  'sendername'   => $ENV{'user.name'},
1.26      www       852:                  'senderdomain' => $ENV{'user.domain'},
                    853:                  'screenname'   => $ENV{'environment.screenname'},
                    854:                  'plainname'    => $ENV{'environment.firstname'}.' '.
                    855: 		                   $ENV{'environment.middlename'}.' '.
                    856:                                    $ENV{'environment.lastname'}.' '.
1.42      www       857:                                    $ENV{'enrironment.generation'},
1.78      raeburn   858:                  'attachmenturl'=> $attachmenturl,
                    859:                  'subject'      => $subject);
1.65      www       860:     if ($ENV{'form.replydisc'}) {
1.66      www       861: 	$contrib{'replyto'}=(split(/\:\:\:/,$ENV{'form.replydisc'}))[1];
1.65      www       862:     }
1.14      www       863:     if ($anon) {
                    864: 	$contrib{'anonymous'}='true';
                    865:     }
1.13      www       866:     if (($symb) && ($email)) {
1.14      www       867:        $status='Adding to class discussion'.($anon?' (anonymous)':'').': '.
1.13      www       868:         &Apache::lonnet::store(\%contrib,$symb,$ENV{'request.course.id'},
                    869:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
1.17      www       870: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
1.21      www       871:         my %storenewentry=($symb => time);
1.63      albertel  872:         $status.='<br />'.&mt('Updating discussion time').': '.
1.21      www       873:         &Apache::lonnet::put('discussiontimes',\%storenewentry,
                    874:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                    875: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
1.13      www       876:     }
1.17      www       877:     my %record=&Apache::lonnet::restore('_discussion');
                    878:     my ($temp)=keys %record;
                    879:     unless ($temp=~/^error\:/) {
                    880:        my %newrecord=();
                    881:        $newrecord{'resource'}=$symb;
                    882:        $newrecord{'subnumber'}=$record{'subnumber'}+1;
1.63      albertel  883:        $status.='<br />'.&mt('Registering').': '.
1.21      www       884:                &Apache::lonnet::cstore(\%newrecord,'_discussion');
1.20      www       885:     }
                    886:     } else {
                    887: 	$status.='Failed.';
1.17      www       888:     }
1.63      albertel  889:     return $status.'<br />';   
1.13      www       890: }
                    891: 
1.33      www       892: # ----------------------------------------------------------- Preview function
                    893: 
                    894: sub show_preview {
                    895:     my $r=shift;
                    896:     my $message=&clear_out_html($ENV{'form.comment'});
                    897:     $message=~s/\n/\<br \/\>/g;
                    898:     $message=&Apache::lontexconvert::msgtexconverted($message);
1.78      raeburn   899:     my $subject=&clear_out_html($ENV{'form.subject'});
                    900:     $subject=~s/\n/\<br \/\>/g;
                    901:     $subject=&Apache::lontexconvert::msgtexconverted($subject);
1.33      www       902:     $r->print('<table border="2"><tr><td>'.
1.78      raeburn   903:        '<b>Subject:</b> '.$subject.'<br /><br />'.
1.33      www       904:        $message.'</td></tr></table>');
                    905: }
                    906: 
                    907: sub generate_preview_button {
1.65      www       908:     my $pre=&mt("Show Preview");
1.33      www       909:     return(<<ENDPREVIEW);
                    910: <form name="preview" action="/adm/feedback?preview=1" method="post" target="preview">
1.78      raeburn   911: <input type="hidden" name="subject">
1.33      www       912: <input type="hidden" name="comment" />
1.65      www       913: <input type="button" value="$pre"
1.87      www       914: onClick="document.mailform.onsubmit();this.form.comment.value=document.mailform.comment.value;this.form.subject.value=document.mailform.subject.value;this.form.submit();" />
1.33      www       915: </form>
                    916: ENDPREVIEW
                    917: }
1.71      www       918: 
1.6       albertel  919: sub handler {
                    920:   my $r = shift;
1.8       www       921:   if ($r->header_only) {
1.71      www       922:      &Apache::loncommon::content_type($r,'text/html');
1.8       www       923:      $r->send_http_header;
                    924:      return OK;
                    925:   }
1.15      www       926: 
                    927: # --------------------------- Get query string for limited number of parameters
                    928: 
1.27      stredwic  929:    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.84      raeburn   930:          ['hide','unhide','deldisc','postdata','preview','replydisc','threadedon','threadedoff','onlyunread','allposts','previous','markread','markonread','markondisp']);
                    931: 
                    932:   if (($ENV{'form.markondisp'}) || ($ENV{'form.markonread'})) {
                    933: # ---------------------- Modify setting for identification of 'NEW' posts in this discussion
1.15      www       934: 
1.84      raeburn   935:       &Apache::loncommon::content_type($r,'text/html');
                    936:       $r->send_http_header;
                    937:       my $symb=$ENV{'form.markondisp'}?$ENV{'form.markondisp'}:$ENV{'form.markonread'};
                    938:       my $ressymb = $symb;
                    939:       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
                    940:       unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
                    941:           $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
                    942:       }
                    943:                                                                                           
                    944:       my %discinfo = ();
                    945:       my $lastkey = $ressymb.'_lastread';
                    946:       my $ondispkey = $ressymb.'_markondisp';
                    947:       if ($ENV{'form.markondisp'}) {
                    948:           $discinfo{$lastkey} = time;
                    949:           $discinfo{$ondispkey} = 1;
                    950:       } elsif ($ENV{'form.markonread'}) {
                    951:           if ( defined($ENV{'previous'}) ) {
                    952:               $discinfo{$lastkey} = $ENV{'previous'};
                    953:           }
                    954:           $discinfo{$ondispkey} = 0;
                    955:       }
                    956:       &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
                    957:       if ($ENV{'form.markondisp'}) {
                    958:           &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'<br />','0','0');
                    959:       } else {
                    960:           &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'<br />','0','0','',$ENV{'form.previous'});
                    961:       }
                    962:       return OK;
                    963:   } elsif (($ENV{'form.allposts'}) || ($ENV{'form.onlyunread'})) {
1.80      raeburn   964: # ----------------------------------------------------------------- Modify display setting for this discussion 
1.78      raeburn   965:       &Apache::loncommon::content_type($r,'text/html');
                    966:       $r->send_http_header;
1.80      raeburn   967:       my $symb=$ENV{'form.allposts'}?$ENV{'form.allposts'}:$ENV{'form.onlyunread'};
1.84      raeburn   968:       my $ressymb = $symb;
1.78      raeburn   969:       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
1.84      raeburn   970:       unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
                    971:           $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
                    972:       }
                    973:       my %discinfo = ();
                    974:       if ($ENV{'form.allposts'}) {
                    975:           $discinfo{$ressymb.'_showonlyunread'} = 0;
                    976:       } elsif ($ENV{'form.onlyunread'}) {
                    977:           $discinfo{$ressymb.'_showonlyunread'} = 1;
                    978:       }
                    979:       &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
                    980:       &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed display status').'<br />','0','0','',$ENV{'form.previous'});
                    981:       return OK;
                    982:   } elsif ($ENV{'form.markread'}) {
                    983: # ----------------------------------------------------------------- Mark new posts as read
                    984:       &Apache::loncommon::content_type($r,'text/html');
                    985:       $r->send_http_header;
                    986:       my $symb=$ENV{'form.markread'};
                    987:       my $ressymb = $symb;
                    988:       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
                    989:       unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
                    990:           $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
1.78      raeburn   991:       }
1.84      raeburn   992:       my %discinfo = ();
                    993:       my $lastkey = $ressymb.'_lastread';
                    994:       $discinfo{$lastkey} = time;
                    995:       &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
                    996:       &redirect_back($r,&Apache::lonnet::clutter($url),&mt('Changed reading status').'<br />','0','0');
1.78      raeburn   997:       return OK;
                    998:   } elsif (($ENV{'form.hide'}) || ($ENV{'form.unhide'})) {
1.15      www       999: # ----------------------------------------------------------------- Hide/unhide
1.71      www      1000:     &Apache::loncommon::content_type($r,'text/html');
1.15      www      1001:     $r->send_http_header;
                   1002: 
                   1003:     my $entry=$ENV{'form.hide'}?$ENV{'form.hide'}:$ENV{'form.unhide'};
                   1004: 
                   1005:     my ($symb,$idx)=split(/\:\:\:/,$entry);
1.52      www      1006:     my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
1.15      www      1007: 
                   1008:     my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
                   1009:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                   1010: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
                   1011: 
                   1012:         
                   1013:     my $currenthidden=$contrib{'hidden'};
                   1014:     
                   1015:     if ($ENV{'form.hide'}) {
                   1016: 	$currenthidden.='.'.$idx.'.';
                   1017:     } else {
                   1018:         $currenthidden=~s/\.$idx\.//g;
                   1019:     }
                   1020:     my %newhash=('hidden' => $currenthidden);
1.38      www      1021: 
                   1022:     &Apache::lonnet::store(\%newhash,$symb,$ENV{'request.course.id'},
                   1023:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                   1024: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
                   1025: 
                   1026:     &redirect_back($r,&Apache::lonnet::clutter($url),
1.80      raeburn  1027:        &mt('Changed discussion status').'<br />','0','0','',$ENV{'form.previous'});
1.69      www      1028:   } elsif (($ENV{'form.threadedon'}) || ($ENV{'form.threadedoff'})) {
1.72      albertel 1029:       &Apache::loncommon::content_type($r,'text/html');
                   1030:       $r->send_http_header;
1.69      www      1031:       if ($ENV{'form.threadedon'}) {
                   1032: 	  &Apache::lonnet::put('environment',{'threadeddiscussion' => 'on'});
                   1033: 	  &Apache::lonnet::appenv('environment.threadeddiscussion' => 'on');
                   1034:       } else {
                   1035:  	  &Apache::lonnet::del('environment',['threadeddiscussion']);
                   1036: 	  &Apache::lonnet::delenv('environment\.threadeddiscussion');
1.72      albertel 1037:       }
1.69      www      1038:       my $symb=$ENV{'form.threadedon'}?$ENV{'form.threadedon'}:$ENV{'form.threadedoff'};
                   1039:       my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
                   1040:       &redirect_back($r,&Apache::lonnet::clutter($url),
1.80      raeburn  1041: 		     &mt('Changed discussion view mode').'<br />','0','0','',$ENV{'form.previous'});
1.38      www      1042:   } elsif ($ENV{'form.deldisc'}) {
                   1043: # --------------------------------------------------------------- Hide for good
1.71      www      1044:     &Apache::loncommon::content_type($r,'text/html');
1.38      www      1045:     $r->send_http_header;
                   1046: 
                   1047:     my $entry=$ENV{'form.deldisc'};
                   1048: 
                   1049:     my ($symb,$idx)=split(/\:\:\:/,$entry);
1.52      www      1050:     my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
1.38      www      1051: 
                   1052:     my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
                   1053:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                   1054: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
                   1055: 
                   1056:         
                   1057:     my $currentdeleted=$contrib{'deleted'};
                   1058:     
                   1059:     $currentdeleted.='.'.$idx.'.';
                   1060: 
                   1061:     my %newhash=('deleted' => $currentdeleted);
1.15      www      1062: 
                   1063:     &Apache::lonnet::store(\%newhash,$symb,$ENV{'request.course.id'},
                   1064:                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
                   1065: 		     $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
                   1066: 
1.30      www      1067:     &redirect_back($r,&Apache::lonnet::clutter($url),
1.80      raeburn  1068:        &mt('Changed discussion status').'<br />','0','0','',$ENV{'form.previous'});
1.33      www      1069:   } elsif ($ENV{'form.preview'}) {
                   1070: # -------------------------------------------------------- User wants a preview
1.76      albertel 1071:       $r->content_type('text/html');
                   1072:       $r->send_http_header;
1.33      www      1073:       &show_preview($r);
1.15      www      1074:   } else {
                   1075: # ------------------------------------------------------------- Normal feedback
1.6       albertel 1076:   my $feedurl=$ENV{'form.postdata'};
                   1077:   $feedurl=~s/^http\:\/\///;
                   1078:   $feedurl=~s/^$ENV{'SERVER_NAME'}//;
                   1079:   $feedurl=~s/^$ENV{'HTTP_HOST'}//;
1.62      www      1080:   $feedurl=~s/\?.+$//;
1.8       www      1081: 
1.66      www      1082:   my $symb;
                   1083:   if ($ENV{'form.replydisc'}) {
                   1084:       $symb=(split(/\:\:\:/,$ENV{'form.replydisc'}))[0];
                   1085:       my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
                   1086:       $feedurl=&Apache::lonnet::clutter($url);
                   1087:   } else {
                   1088:       $symb=&Apache::lonnet::symbread($feedurl);
                   1089:   }
1.31      www      1090:   unless ($symb) {
                   1091:       $symb=$ENV{'form.symb'};
                   1092:       if ($symb) {
1.52      www      1093: 	  my ($map,$id,$url)=&Apache::lonnet::decode_symb($symb);
1.31      www      1094:           $feedurl=&Apache::lonnet::clutter($url);
                   1095:       }
                   1096:   }
1.8       www      1097:   my $goahead=1;
                   1098:   if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form)$/) {
                   1099:       unless ($symb) { $goahead=0; }
                   1100:   }
1.74      www      1101:   # backward compatibility (bulltin boards used to be 'wrapped')
1.73      albertel 1102:   if ($feedurl=~m|^/adm/wrapper/adm/.*/bulletinboard$|) {
                   1103:       $feedurl=~s|^/adm/wrapper||;
                   1104:   }
1.8       www      1105:   if ($goahead) {
                   1106: # Go ahead with feedback, no ambiguous reference
1.71      www      1107:     &Apache::loncommon::content_type($r,'text/html');
1.8       www      1108:     $r->send_http_header;
1.6       albertel 1109:   
1.8       www      1110:     if (
1.7       albertel 1111:       (
                   1112:        ($feedurl=~m:^/res:) && ($feedurl!~m:^/res/adm:)
                   1113:       ) 
                   1114:       || 
                   1115:       ($ENV{'request.course.id'} && ($feedurl!~m:^/adm:))
1.31      www      1116:       ||
                   1117:       ($ENV{'request.course.id'} && ($symb=~/^bulletin\_\_\_/))
1.7       albertel 1118:      ) {
1.6       albertel 1119: # --------------------------------------------------- Print login screen header
                   1120:     unless ($ENV{'form.sendit'}) {
                   1121:       my $options=&screen_header($feedurl);
                   1122:       if ($options) {
                   1123: 	&mail_screen($r,$feedurl,$options);
                   1124:       } else {
                   1125: 	&fail_redirect($r,$feedurl);
                   1126:       }
                   1127:     } else {
                   1128:       
                   1129: # Get previous user input
1.9       albertel 1130:       my $prevattempts=&Apache::loncommon::get_previous_attempt(
1.11      albertel 1131:             $symb,$ENV{'user.name'},$ENV{'user.domain'},
1.9       albertel 1132:             $ENV{'request.course.id'});
1.6       albertel 1133: 
                   1134: # Get output from resource
                   1135:       my $usersaw=&resource_output($feedurl);
                   1136: 
1.50      albertel 1137: # Get resource answer (need to allow student to view grades for this to work)
                   1138:       &Apache::lonnet::appenv(('allowed.vgr'=>'F'));
1.40      albertel 1139:       my $useranswer=&Apache::loncommon::get_student_answers(
                   1140:                        $symb,$ENV{'user.name'},$ENV{'user.domain'},
                   1141: 		       $ENV{'request.course.id'});
1.50      albertel 1142:       &Apache::lonnet::delenv('allowed.vgr');
1.42      www      1143: # Get attachments, if any, and not too large
                   1144:       my $attachmenturl='';
                   1145:       if ($ENV{'form.attachment.filename'}) {
                   1146: 	  unless (length($ENV{'form.attachment'})>131072) {
1.82      albertel 1147: 	      $attachmenturl=&Apache::lonnet::userfileupload('attachment',undef,'feedback');
1.42      www      1148: 	  }
                   1149:       }
1.6       albertel 1150: # Filter HTML out of message (could be nasty)
1.39      www      1151:       my $message=&clear_out_html($ENV{'form.comment'});
1.6       albertel 1152: 
                   1153: # Assemble email
1.8       www      1154:       my ($email,$citations)=&assemble_email($feedurl,$message,$prevattempts,
1.40      albertel 1155:           $usersaw,$useranswer);
                   1156:  
1.6       albertel 1157: # Who gets this?
                   1158:       my ($typestyle,%to) = &decide_receiver($feedurl);
                   1159: 
                   1160: # Actually send mail
1.43      www      1161:       my ($status,$numsent)=&send_msg($feedurl,$email,$citations,
                   1162:           $attachmenturl,%to);
1.13      www      1163: 
                   1164: # Discussion? Store that.
                   1165: 
1.32      albertel 1166:       my $numpost=0;
1.13      www      1167:       if ($ENV{'form.discuss'}) {
1.78      raeburn  1168:           my $subject = &clear_out_html($ENV{'form.subject'});
                   1169: 	  $typestyle.=&adddiscuss($symb,$message,0,$attachmenturl,$subject);
1.32      albertel 1170: 	  $numpost++;
1.13      www      1171:       }
1.6       albertel 1172: 
1.14      www      1173:       if ($ENV{'form.anondiscuss'}) {
1.78      raeburn  1174:           my $subject = &clear_out_html($ENV{'form.subject'});
                   1175: 	  $typestyle.=&adddiscuss($symb,$message,1,$attachmenturl,$subject);
1.32      albertel 1176: 	  $numpost++;
1.14      www      1177:       }
                   1178: 
                   1179: 
1.6       albertel 1180: # Receipt screen and redirect back to where came from
1.80      raeburn  1181:       &redirect_back($r,$feedurl,$typestyle,$numsent,$numpost,$status,$ENV{'form.previous'});
1.6       albertel 1182: 
                   1183:     }
1.8       www      1184:    } else {
1.7       albertel 1185: # Unable to give feedback
1.6       albertel 1186:     &no_redirect_back($r,$feedurl);
1.8       www      1187:    }
                   1188:   } else {
                   1189: # Ambiguous Problem Resource
1.60      albertel 1190:       if ( &Apache::lonnet::mod_perl_version() == 2 ) {
1.53      albertel 1191: 	  &Apache::lonnet::cleanenv();
1.58      albertel 1192:       }
1.53      albertel 1193:       $r->internal_redirect('/adm/ambiguous');
1.6       albertel 1194:   }
1.15      www      1195: }
1.6       albertel 1196:   return OK;
1.1       www      1197: } 
                   1198: 
                   1199: 1;
                   1200: __END__

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.