--- loncom/interface/lonfeedback.pm 2004/08/31 18:28:18 1.120
+++ loncom/interface/lonfeedback.pm 2005/04/07 06:56:23 1.157
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Feedback
#
-# $Id: lonfeedback.pm,v 1.120 2004/08/31 18:28:18 albertel Exp $
+# $Id: lonfeedback.pm,v 1.157 2005/04/07 06:56:23 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -35,19 +35,22 @@ use Apache::lonmsg();
use Apache::loncommon();
use Apache::lontexconvert();
use Apache::lonlocal; # must not have ()
+use Apache::lonnet;
use Apache::lonhtmlcommon();
+use Apache::lonnavmaps;
+use Apache::lonenc();
use HTML::LCParser();
use Apache::lonspeller();
use Cwd;
sub discussion_open {
- my ($status)=@_;
+ my ($status,$symb)=@_;
if (defined($status) &&
!($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
|| $status eq 'OPEN')) {
return 0;
}
- my $close=&Apache::lonnet::EXT('resource.0.discussend');
+ my $close=&Apache::lonnet::EXT('resource.0.discussend',$symb);
if (defined($close) && $close ne '' && $close < time) {
return 0;
}
@@ -59,45 +62,46 @@ sub discussion_visible {
if (not &discussion_open($status)) {
my $hidden=&Apache::lonnet::EXT('resource.0.discusshide');
if (lc($hidden) eq 'yes' or $hidden eq '' or !defined($hidden)) {
- return 0;
+ if (!$env{'request.role.adv'}) { return 0; }
}
}
return 1;
}
sub list_discussion {
- my ($mode,$status,$symb)=@_;
- my $outputtarget=$ENV{'form.grade_target'};
- if (defined($ENV{'form.export'})) {
- if($ENV{'form.export'}) {
+ my ($mode,$status,$ressymb,$imsextras)=@_;
+ my $outputtarget=$env{'form.grade_target'};
+ if (defined($env{'form.export'})) {
+ if($env{'form.export'}) {
+ $outputtarget = 'export';
+ }
+ }
+ if (defined($imsextras)) {
+ if ($$imsextras{'caller'} eq 'imsexport') {
$outputtarget = 'export';
}
- }
+ }
if (not &discussion_visible($status)) { return ''; }
my @bgcols = ("#cccccc","#eeeeee");
my $discussiononly=0;
if ($mode eq 'board') { $discussiononly=1; }
- unless ($ENV{'request.course.id'}) { return ''; }
- my $crs='/'.$ENV{'request.course.id'};
- my $cid=$ENV{'request.course.id'};
- if ($ENV{'request.course.sec'}) {
- $crs.='_'.$ENV{'request.course.sec'};
- }
- $crs=~s/\_/\//g;
- unless ($symb) {
- $symb=&Apache::lonnet::symbread();
+ unless ($env{'request.course.id'}) { return ''; }
+ my $crs='/'.$env{'request.course.id'};
+ my $cid=$env{'request.course.id'};
+ if ($env{'request.course.sec'}) {
+ $crs.='_'.$env{'request.course.sec'};
}
- unless ($symb) { return ''; }
+ $crs=~s/\_/\//g;
+ unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); }
+ unless ($ressymb) { return ''; }
+ $ressymb=&wrap_symb($ressymb);
+ my $encsymb=&Apache::lonenc::check_encrypt($ressymb);
+ my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
+ && ($ressymb=~/\.(problem|exam|quiz|assess|survey|form)$/));
+
my %usernamesort = ();
my %namesort =();
my %subjectsort = ();
-# backward compatibility (bulletin boards used to be 'wrapped')
- my $ressymb=$symb;
- if ($mode eq 'board') {
- unless ($ressymb =~ m|bulletin___\d+___adm/wrapper|) {
- $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
- }
- }
# Get discussion display settings for this discussion
my $lastkey = $ressymb.'_lastread';
@@ -108,8 +112,8 @@ sub list_discussion {
my $userpickkey = $ressymb.'_userpick';
my $toggkey = $ressymb.'_readtoggle';
my $readkey = $ressymb.'_read';
-
- my %dischash = &Apache::lonnet::get('nohist_'.$ENV{'request.course.id'}.'_discuss',[$lastkey,$showkey,$markkey,$visitkey,$ondispkey,$userpickkey,$toggkey,$readkey],$ENV{'user.domain'},$ENV{'user.name'});
+ $ressymb=$encsymb;
+ my %dischash = &Apache::lonnet::get('nohist_'.$env{'request.course.id'}.'_discuss',[$lastkey,$showkey,$markkey,$visitkey,$ondispkey,$userpickkey,$toggkey,$readkey],$env{'user.domain'},$env{'user.name'});
my %discinfo = ();
my $showonlyunread = 0;
my $showunmark = 0;
@@ -122,12 +126,22 @@ sub list_discussion {
# Retain identification of "NEW" posts identified in last display, if continuing 'previous' browsing of posts.
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['previous','sortposts','rolefilter','statusfilter','sectionpick','totposters']);
- my $sortposts = $ENV{'form.sortposts'};
- my $rolefilter = $ENV{'form.rolefilter'};
- my $statusfilter = $ENV{'form.statusfilter'};
- my $sectionpick = $ENV{'form.sectionpick'};
- my $totposters = $ENV{'form.totposters'};
- $previous = $ENV{'form.previous'};
+ my $sortposts = $env{'form.sortposts'};
+ my $statusfilter = $env{'form.statusfilter'};
+ my @sectionpick = ();
+ if ($env{'form.sectionpick'} =~ /,/) {
+ @sectionpick = split/,/,$env{'form.sectionpick'};
+ } else {
+ $sectionpick[0] = $env{'form.sectionpick'};
+ }
+ my @rolefilter = ();
+ if ($env{'form.rolefilter'} =~ /,/) {
+ @rolefilter = split/,/,$env{'form.rolefilter'};
+ } else {
+ $rolefilter[0] = $env{'form.rolefilter'};
+ }
+ my $totposters = $env{'form.totposters'};
+ $previous = $env{'form.previous'};
if ($previous > 0) {
$prevread = $previous;
} elsif (defined($dischash{$lastkey})) {
@@ -139,22 +153,27 @@ sub list_discussion {
# Get information about students and non-students in course for filtering display of posts
my %roleshash = ();
my %roleinfo = ();
- if ($rolefilter) {
- %roleshash = &Apache::lonnet::dump('nohist_userroles',$ENV{'course.'.$ENV{'request.course.id'}.'.domain'},$ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ if ($env{'form.rolefilter'}) {
+ %roleshash = &Apache::lonnet::dump('nohist_userroles',$env{'course.'.$env{'request.course.id'}.'.domain'},$env{'course.'.$env{'request.course.id'}.'.num'});
foreach (keys %roleshash) {
my ($role,$uname,$udom,$sec) = split/:/,$_;
+ if ($role =~ /^cr/) {
+ $role = 'cr';
+ }
my ($end,$start) = split/:/,$roleshash{$_};
my $now = time;
my $status = 'Active';
if (($now < $start) || ($end > 0 && $now > $end)) {
$status = 'Expired';
}
- push @{$roleinfo{$uname.':'.$udom}}, $role.':'.$sec.':'.$status;
+ if ($uname && $udom) {
+ push @{$roleinfo{$uname.':'.$udom}}, $role.':'.$sec.':'.$status;
+ }
}
my ($classlist) = &Apache::loncoursedata::get_classlist(
- $ENV{'request.course.id'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ $env{'request.course.id'},
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
my $sec_index = &Apache::loncoursedata::CL_SECTION();
my $status_index = &Apache::loncoursedata::CL_STATUS();
while (my ($student,$data) = each %$classlist) {
@@ -165,40 +184,43 @@ sub list_discussion {
}
# Get discussion display default settings for user
- my %userenv = &Apache::lonnet::get('environment',['discdisplay','discmarkread'],$ENV{'user.domain'},$ENV{'user.name'});
- my $discdisplay=$userenv{'discdisplay'};
- if ($discdisplay eq 'unread') {
+ if ($env{'environment.discdisplay'} eq 'unread') {
$showonlyunread = 1;
}
- my $discmarkread=$userenv{'discmarkread'};
- if ($discmarkread eq 'ondisp') {
+ if ($env{'environment.discmarkread'} eq 'ondisp') {
$markondisp = 1;
}
# Override user's default if user specified display setting for this discussion
if (defined($dischash{$ondispkey})) {
- $markondisp = $dischash{$ondispkey};
+ unless ($dischash{$ondispkey} eq '') {
+ $markondisp = $dischash{$ondispkey};
+ }
}
if ($markondisp) {
$discinfo{$lastkey} = time;
}
if (defined($dischash{$showkey})) {
- $showonlyunread = $dischash{$showkey};
+ unless ($dischash{$showkey} eq '') {
+ $showonlyunread = $dischash{$showkey};
+ }
}
if (defined($dischash{$markkey})) {
- $showunmark = $dischash{$markkey};
+ unless ($dischash{$markkey} eq '') {
+ $showunmark = $dischash{$markkey};
+ }
}
if (defined($dischash{$visitkey})) {
- $visit = $dischash{$visitkey};
+ unless ($dischash{$visitkey} eq '') {
+ $visit = $dischash{$visitkey};
+ }
}
$visit ++;
my $seeid=&Apache::lonnet::allowed('rin',$crs);
- my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
- && ($symb=~/\.(problem|exam|quiz|assess|survey|form)$/));
my @discussionitems=();
my %shown = ();
my @posteridentity=();
@@ -215,16 +237,16 @@ sub list_discussion {
my $maxdepth=0;
my $target='';
- unless ($ENV{'browser.interface'} eq 'textual' ||
- $ENV{'environment.remote'} eq 'off' ) {
+ unless ($env{'browser.interface'} eq 'textual' ||
+ $env{'environment.remote'} eq 'off' ) {
$target='target="LONcom"';
}
my $now = time;
$discinfo{$visitkey} = $visit;
- &Apache::lonnet::put('nohist_'.$ENV{'request.course.id'}.'_discuss',\%discinfo,$ENV{'user.domain'},$ENV{'user.name'});
- &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$ressymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$statusfilter,$toggkey,$outputtarget);
+ &Apache::lonnet::put('nohist_'.$env{'request.course.id'}.'_discuss',\%discinfo,$env{'user.domain'},$env{'user.name'});
+ &build_posting_display(\%usernamesort,\%subjectsort,\%namesort,\%notshown,\%newitem,\%dischash,\%shown,\%alldiscussion,\%imsitems,\%imsfiles,\%roleinfo,\@discussionitems,\@replies,\@depth,\@posters,\$maxdepth,\$visible,\$newpostsflag,\$current,$status,$viewgrades,$seeid,$prevread,$sortposts,$encsymb,$target,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,$statusfilter,$toggkey,$outputtarget);
my $discussion='';
my $manifestfile;
@@ -235,7 +257,7 @@ sub list_discussion {
my $function = &Apache::loncommon::get_users_function();
my $color = &Apache::loncommon::designparm($function.'.tabbg',
- $ENV{'user.domain'});
+ $env{'user.domain'});
my %lt = &Apache::lonlocal::texthash(
'cuse' => 'Current discussion settings',
'allposts' => 'All posts',
@@ -301,30 +323,40 @@ sub list_discussion {
if ($visible) {
# Print the discusssion
if ($outputtarget eq 'tex') {
- $discussion.='
'. - &mt('Feedback to resource author').'
'; + ''; } if (&feedback_available(1)) { $msgoptions.= - '
#
#
%html=(B=>1, I=>1, P=>1, A=>1, LI=>1, OL=>1, UL=>1, EM=>1,
BR=>1, TT=>1, STRONG=>1, BLOCKQUOTE=>1, DIV=>1, IMG=>1,
- M=>1, SUB=>1, SUP=>1, SPAN=>1,
+ M=>1, ALGEBRA=>1, SUB=>1, SUP=>1, SPAN=>1,
H1=>1, H2=>1, H3=>1, H4=>1, H5=>1);
}
# Do the substitution of everything that is not explicitly allowed
@@ -2216,8 +2342,6 @@ sub clear_out_html {
sub assemble_email {
my ($feedurl,$message,$prevattempts,$usersaw,$useranswer)=@_;
my $email=<<"ENDEMAIL";
-Refers to $feedurl
-
$message
ENDEMAIL
my $citations=<<"ENDCITE";
@@ -2240,7 +2364,7 @@ sub secapply {
my ($adr,$sections)=($rec=~/^([^\(]+)\(([^\)]+)\)/);
if ($sections) {
foreach (split(/\;/,$sections)) {
- if (($_ eq $ENV{'request.course.sec'}) ||
+ if (($_ eq $env{'request.course.sec'}) ||
($defaultflag && ($_ eq '*'))) {
return $adr;
}
@@ -2255,33 +2379,33 @@ sub decide_receiver {
my ($feedurl,$author,$question,$course,$policy,$defaultflag) = @_;
my $typestyle='';
my %to=();
- if ($ENV{'form.author'}||$author) {
+ if ($env{'form.author'}||$author) {
$typestyle.='Submitting as Author Feedback
';
$feedurl=~/^\/res\/(\w+)\/(\w+)\//;
$to{$2.':'.$1}=1;
}
- if ($ENV{'form.question'}||$question) {
+ if ($env{'form.question'}||$question) {
$typestyle.='Submitting as Question
';
foreach (split(/\,/,
- $ENV{'course.'.$ENV{'request.course.id'}.'.question.email'})
+ $env{'course.'.$env{'request.course.id'}.'.question.email'})
) {
my $rec=&secapply($_,$defaultflag);
if ($rec) { $to{$rec}=1; }
}
}
- if ($ENV{'form.course'}||$course) {
+ if ($env{'form.course'}||$course) {
$typestyle.='Submitting as Comment
';
foreach (split(/\,/,
- $ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'})
+ $env{'course.'.$env{'request.course.id'}.'.comment.email'})
) {
my $rec=&secapply($_,$defaultflag);
if ($rec) { $to{$rec}=1; }
}
}
- if ($ENV{'form.policy'}||$policy) {
+ if ($env{'form.policy'}||$policy) {
$typestyle.='Submitting as Policy Feedback
';
foreach (split(/\,/,
- $ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'})
+ $env{'course.'.$env{'request.course.id'}.'.policy.email'})
) {
my $rec=&secapply($_,$defaultflag);
if ($rec) { $to{$rec}=1; }
@@ -2334,40 +2458,47 @@ sub send_msg {
sub adddiscuss {
my ($symb,$email,$anon,$attachmenturl,$subject)=@_;
my $status='';
- if (&discussion_open() &&
- &Apache::lonnet::allowed('pch',$ENV{'request.course.id'}.
- ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
+ my $realsymb;
+ if ($symb=~/^bulletin___/) {
+ my $filename=(&Apache::lonnet::decode_symb($symb))[2];
+ $filename=~s|^adm/wrapper/||;
+ $realsymb=&Apache::lonnet::symbread($filename);
+ }
+ if (&discussion_open(undef,$realsymb) &&
+ &Apache::lonnet::allowed('pch',$env{'request.course.id'}.
+ ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
my %contrib=('message' => $email,
- 'sendername' => $ENV{'user.name'},
- 'senderdomain' => $ENV{'user.domain'},
- 'screenname' => $ENV{'environment.screenname'},
- 'plainname' => $ENV{'environment.firstname'}.' '.
- $ENV{'environment.middlename'}.' '.
- $ENV{'environment.lastname'}.' '.
- $ENV{'enrironment.generation'},
+ 'sendername' => $env{'user.name'},
+ 'senderdomain' => $env{'user.domain'},
+ 'screenname' => $env{'environment.screenname'},
+ 'plainname' => $env{'environment.firstname'}.' '.
+ $env{'environment.middlename'}.' '.
+ $env{'environment.lastname'}.' '.
+ $env{'enrironment.generation'},
'attachmenturl'=> $attachmenturl,
'subject' => $subject);
- if ($ENV{'form.replydisc'}) {
- $contrib{'replyto'}=(split(/\:\:\:/,$ENV{'form.replydisc'}))[1];
+ if ($env{'form.replydisc'}) {
+ $contrib{'replyto'}=(split(/\:\:\:/,$env{'form.replydisc'}))[1];
}
if ($anon) {
$contrib{'anonymous'}='true';
}
if (($symb) && ($email)) {
- if ($ENV{'form.editdisc'}) {
+ if ($env{'form.editdisc'}) {
my %newcontrib = ();
$contrib{'ip'}=$ENV{'REMOTE_ADDR'};
$contrib{'host'}=$Apache::lonnet::perlvar{'lonHostID'};
$contrib{'timestamp'} = time;
$contrib{'history'} = '';
my $numoldver = 0;
- my ($oldsymb,$oldidx)=split(/\:\:\:/,$ENV{'form.editdisc'});
+ my ($oldsymb,$oldidx)=split(/\:\:\:/,$env{'form.editdisc'});
+ &Apache::lonenc::check_decrypt(\$oldsymb);
$oldsymb=~s|(bulletin___\d+___)adm/wrapper/|$1|;
# get timestamp for last post and history
- my %oldcontrib=&Apache::lonnet::restore($oldsymb,$ENV{'request.course.id'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ my %oldcontrib=&Apache::lonnet::restore($oldsymb,$env{'request.course.id'},
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
if (defined($oldcontrib{$oldidx.':replyto'})) {
$contrib{'replyto'} = $oldcontrib{$oldidx.':replyto'};
}
@@ -2402,22 +2533,22 @@ sub adddiscuss {
my $key = $oldidx.':'.&Apache::lonnet::escape($oldsymb).':'.$_;
$newcontrib{$key} = $contrib{$_};
}
- my $put_reply = &Apache::lonnet::putstore($ENV{'request.course.id'},
+ my $put_reply = &Apache::lonnet::putstore($env{'request.course.id'},
\%newcontrib,
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
$status='Editing class discussion'.($anon?' (anonymous)':'');
} else {
$status='Adding to class discussion'.($anon?' (anonymous)':'').': '.
- &Apache::lonnet::store(\%contrib,$symb,$ENV{'request.course.id'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ &Apache::lonnet::store(\%contrib,$symb,$env{'request.course.id'},
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
}
my %storenewentry=($symb => time);
$status.='
'.&mt('Updating discussion time').': '.
&Apache::lonnet::put('discussiontimes',\%storenewentry,
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
}
my %record=&Apache::lonnet::restore('_discussion');
my ($temp)=keys %record;
@@ -2438,16 +2569,20 @@ sub adddiscuss {
sub show_preview {
my $r=shift;
- my $message=&clear_out_html($ENV{'form.comment'});
+ &Apache::loncommon::content_type($r,'text/html');
+ $r->send_http_header;
+ my $message=&clear_out_html($env{'form.comment'});
$message=~s/\n/\
/g;
$message=&Apache::lonspeller::markeduptext($message);
$message=&Apache::lontexconvert::msgtexconverted($message);
- my $subject=&clear_out_html($ENV{'form.subject'});
+ my $subject=&clear_out_html($env{'form.subject'});
$subject=~s/\n/\
/g;
$subject=&Apache::lontexconvert::msgtexconverted($subject);
- $r->print('
');
+ my $html=&Apache::lonxml::xmlbegin();
+ $r->print($html.''.
+ ''.
- 'Subject: '.$subject.'
'.
- $message.'
');
}
sub generate_preview_button {
@@ -2464,11 +2599,12 @@ ENDPREVIEW
sub modify_attachments {
my ($r,$currnewattach,$currdelold,$symb,$idx,$attachmenturls)=@_;
- my $subject=&clear_out_html($ENV{'form.subject'});
+ my $orig_subject = &Apache::lonnet::unescape($env{'form.subject'});
+ my $subject=&clear_out_html($orig_subject);
$subject=~s/\n/\'.
+ 'Subject: '.$subject.'
'.
+ $message.'
/g;
$subject=&Apache::lontexconvert::msgtexconverted($subject);
- my $timestamp=$ENV{'form.timestamp'};
- my $numoldver=$ENV{'form.numoldver'};
+ my $timestamp=$env{'form.timestamp'};
+ my $numoldver=$env{'form.numoldver'};
my $bodytag=&Apache::loncommon::bodytag('Discussion Post Attachments',
'','');
my $msg = '';
@@ -2477,8 +2613,10 @@ sub modify_attachments {
if ($idx) {
&extract_attachments($attachmenturls,$idx,$numoldver,\$msg,\%attachments,\%currattach,$currdelold);
}
+ &Apache::lonenc::check_encrypt(\$symb);
+ my $html=&Apache::lonxml::xmlbegin();
$r->print(<