--- loncom/interface/lonfeedback.pm 2001/02/06 14:22:30 1.3 +++ loncom/interface/lonfeedback.pm 2002/01/01 15:02:31 1.21 @@ -1,6 +1,30 @@ # The LearningOnline Network # Feedback # +# $Id: lonfeedback.pm,v 1.21 2002/01/01 15:02:31 www Exp $ +# +# Copyright Michigan State University Board of Trustees +# +# This file is part of the LearningOnline Network with CAPA (LON-CAPA). +# +# LON-CAPA is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LON-CAPA is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LON-CAPA; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# /home/httpd/html/adm/gpl.txt +# +# http://www.lon-capa.org/ +# # (Internal Server Error Handler # # (Login Screen @@ -9,212 +33,450 @@ # # 3/1/1 Gerd Kortemeyer) # -# 3/1,2/3,2/5,2/6 Gerd Kortemeyer -# +# 3/1,2/3,2/5,2/6,2/8 Gerd Kortemeyer +# 2/9 Guy Albertelli +# 2/10 Gerd Kortemeyer +# 2/13 Guy Albertelli +# 7/25 Gerd Kortemeyer +# 7/26 Guy Albertelli +# 7/26,8/10,10/1,11/5,11/6,12/27,12/29 Gerd Kortemeyer + + package Apache::lonfeedback; use strict; use Apache::Constants qw(:common); use Apache::lonmsg(); +use Apache::loncommon(); -sub handler { - my $r = shift; - $r->content_type('text/html'); - $r->send_http_header; - return OK if $r->header_only; - - my $feedurl=$ENV{'form.postdata'}; - $feedurl=~s/^http\:\/\///; - $feedurl=~s/^$ENV{'SERVER_NAME'}//; - $feedurl=~s/^$ENV{'HTTP_HOST'}//; - - if (($feedurl=~/^\/res/) || ($ENV{'request.course.id'})) { -# --------------------------------------------------- Print login screen header - unless ($ENV{'form.sendit'}) { - my $options=''; - if ($feedurl=~/^\/res/) { - $options= - '
Feedback to resource author';
- }
- if ($ENV{'course.'.$ENV{'request.course.id'}.'.question.email'}) {
- $options.=
- ' Feedback to resource author';
+ }
+ if ($ENV{'course.'.$ENV{'request.course.id'}.'.question.email'}) {
+ $options.=
+ ' ','0');
+
+
+ } else {
+# ------------------------------------------------------------- Normal feedback
+ my $feedurl=$ENV{'form.postdata'};
+ $feedurl=~s/^http\:\/\///;
+ $feedurl=~s/^$ENV{'SERVER_NAME'}//;
+ $feedurl=~s/^$ENV{'HTTP_HOST'}//;
+
+ my $symb=&Apache::lonnet::symbread($feedurl);
+ my $goahead=1;
+ if ($feedurl=~/\.(problem|exam|quiz|assess|survey|form)$/) {
+ unless ($symb) { $goahead=0; }
+ }
+
+ if ($goahead) {
+# Go ahead with feedback, no ambiguous reference
+ $r->content_type('text/html');
+ $r->send_http_header;
+
+ if (
+ (
+ ($feedurl=~m:^/res:) && ($feedurl!~m:^/res/adm:)
+ )
+ ||
+ ($ENV{'request.course.id'} && ($feedurl!~m:^/adm:))
+ ) {
+# --------------------------------------------------- Print login screen header
+ unless ($ENV{'form.sendit'}) {
+ my $options=&screen_header($feedurl);
+ if ($options) {
+ &mail_screen($r,$feedurl,$options);
+ } else {
+ &fail_redirect($r,$feedurl);
+ }
+ } else {
+
+# Get previous user input
+ my $prevattempts=&Apache::loncommon::get_previous_attempt(
+ $symb,$ENV{'user.name'},$ENV{'user.domain'},
+ $ENV{'request.course.id'});
+
+# Get output from resource
+ my $usersaw=&resource_output($feedurl);
+
+# Filter HTML out of message (could be nasty)
+ my $message=&clear_out_html;
+
+# Assemble email
+ my ($email,$citations)=&assemble_email($feedurl,$message,$prevattempts,
+ $usersaw);
+
+# Who gets this?
+ my ($typestyle,%to) = &decide_receiver($feedurl);
+
+# Actually send mail
+ my ($status,$numsent)=&send_msg($feedurl,$email,$citations,%to);
+
+# Discussion? Store that.
+
+ if ($ENV{'form.discuss'}) {
+ $typestyle.=&adddiscuss($symb,$message);
+ }
+
+ if ($ENV{'form.anondiscuss'}) {
+ $typestyle.=&adddiscuss($symb,$message,1);
+ }
+
+
+# Receipt screen and redirect back to where came from
+ &redirect_back($r,$feedurl,$typestyle,$numsent,$status);
+
+ }
+ } else {
+# Unable to give feedback
+ &no_redirect_back($r,$feedurl);
+ }
+ } else {
+# Ambiguous Problem Resource
+ $r->internal_redirect('/adm/ambiguous');
+ }
+}
+ return OK;
}
1;
@@ -222,3 +484,4 @@ __END__
+
Question about resource content';
- }
- if ($ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'}) {
- $options.=
- '
'.
- 'Question/Comment/Feedback about course content';
- }
- if ($ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'}) {
- $options.=
- '
'.
- 'Question/Comment/Feedback about course policy';
- }
- $r->print(<Feedback
$feedurl
-
ENDDOCUMENT
-} else {
-#
-# Get previous user input
-#
- my $symb=&Apache::lonnet::symbread($feedurl);
- my $prevattempts='';
- if ($symb) {
- my $answer=&Apache::lonnet::reply(
- "restore:".$ENV{'user.domain'}.':'.$ENV{'user.name'}.':'.
- $ENV{'request.course.id'}.':'.
- &Apache::lonnet::escape($symb),
- $ENV{'user.home'});
- my %returnhash=();
- map {
- my ($name,$value)=split(/\=/,$_);
- $returnhash{&Apache::lonnet::unescape($name)}=
- &Apache::lonnet::unescape($value);
- } split(/\&/,$answer);
- my %lasthash=();
- my $version;
- for ($version=1;$version<=$returnhash{'version'};$version++) {
- map {
- $lasthash{$_}=$returnhash{$version.':'.$_};
- } split(/\:/,$returnhash{$version.':keys'});
- }
- $prevattempts='
';
- }
-#
-# Get output from resource
-#
- my $usersaw=&Apache::lonnet::ssi($feedurl);
- $usersaw=~s/\]*\>//gi;
- $usersaw=~s/\<\/body\>//gi;
- $usersaw=~s/\//gi;
- $usersaw=~s/\<\/html\>//gi;
- $usersaw=~s/\//gi;
- $usersaw=~s/\<\/head\>//gi;
- $usersaw=~s/action\s*\=/would_be_action\=/gi;
-#
-# Filter HTML out of message (could be nasty)
-#
- my $message=$ENV{'form.comment'};
- $message=~s/\\<\;/g;
- $message=~s/\>/\>\;/g;
+}
-#
-# Assemble email
-#
- my $email=<<"ENDEMAIL";
-Refers to $feedurl
-History ';
- map {
- $prevattempts.=''.$_.' ';
- } keys %lasthash;
- for ($version=1;$version<=$returnhash{'version'};$version++) {
- $prevattempts.='Attempt '.$version.' ';
- map {
- $prevattempts.=''.$returnhash{$version.':'.$_}.' ';
- } keys %lasthash;
- }
- $prevattempts.='Current ';
- map {
- $prevattempts.=''.$lasthash{$_}.' ';
- } keys %lasthash;
- $prevattempts.='
-Message
-
-$message
-
-
-Previous attempts of student (if applicable)
-$prevattempts
-
-Original screen output (if applicable)
-$usersaw
-ENDEMAIL
-#
-# Who gets this?
-#
- my %to=();
- if ($ENV{'form.author'}) {
- $feedurl=~/^\/res\/(\w+)\/(\w+)\//;
- $to{$2.':'.$1}=1;
- }
- if ($ENV{'form.question'}) {
- map {
- $to{$_}=1;
- } split(/\,/,
- $ENV{'course.'.$ENV{'request.course.id'}.'.question.email'});
- }
- if ($ENV{'form.comment'}) {
- map {
- $to{$_}=1;
- } split(/\,/,
- $ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'});
- }
- if ($ENV{'form.policy'}) {
- map {
- $to{$_}=1;
- } split(/\,/,
- $ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'});
- }
-#
-# Actually send mail
-#
- my $status='';
- map {
- if ($_) {
- unless (
- &Apache::lonmsg::user_normal_msg(split(/\:/,$_),'Feedback '.$feedurl,
- $email) eq 'ok') {
- $status.='
Error sending message to '.$_.'
';
- }
- }
- } keys %to;
-#
-# Receipt screen and redirect back to where came from
-#
- print (<
Question about resource content';
+ }
+ if ($ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'}) {
+ $options.=
+ '
'.
+ 'Question/Comment/Feedback about course content';
+ }
+ if ($ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'}) {
+ $options.=
+ '
'.
+ 'Question/Comment/Feedback about course policy';
+ }
+
+ if ($ENV{'request.course.id'}) {
+ if (&Apache::lonnet::allowed('pch',$ENV{'request.course.id'})) {
+ $options.='
'.
+ 'Contribution to course discussion of resource';
+ $options.='
'.
+ 'Anonymous contribution to course discussion of resource'.
+ ' (name only visible to course faculty)';
+ }
+ }
+ return $options;
+}
+
+sub resource_output {
+ my ($feedurl) = @_;
+ my $usersaw=&Apache::lonnet::ssi($feedurl);
+ $usersaw=~s/\Previous attempts of student (if applicable)
+$prevattempts
+
+Original screen output (if applicable)
+$usersaw
+ENDCITE
+ return ($email,$citations);
+}
+
+sub decide_receiver {
+ my ($feedurl) = @_;
+ my $typestyle='';
+ my %to=();
+ if ($ENV{'form.author'}) {
+ $typestyle.='Submitting as Author Feedback
';
+ $feedurl=~/^\/res\/(\w+)\/(\w+)\//;
+ $to{$2.':'.$1}=1;
+ }
+ if ($ENV{'form.question'}) {
+ $typestyle.='Submitting as Question
';
+ map {
+ $to{$_}=1;
+ } split(/\,/,
+ $ENV{'course.'.$ENV{'request.course.id'}.'.question.email'});
+ }
+ if ($ENV{'form.course'}) {
+ $typestyle.='Submitting as Comment
';
+ map {
+ $to{$_}=1;
+ } split(/\,/,
+ $ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'});
+ }
+ if ($ENV{'form.policy'}) {
+ $typestyle.='Submitting as Policy Feedback
';
+ map {
+ $to{$_}=1;
+ } split(/\,/,
+ $ENV{'course.'.$ENV{'request.course.id'}.'.policy.email'});
+ }
+ return ($typestyle,%to);
+}
+
+sub send_msg {
+ my ($feedurl,$email,$citations,%to)=@_;
+ my $status='';
+ my $sendsomething=0;
+ map {
+ if ($_) {
+ unless (&Apache::lonmsg::user_normal_msg(split(/\:/,$_),
+ 'Feedback '.$feedurl,$email,$citations) eq 'ok') {
+ $status.='
Error sending message to '.$_.'
';
+ } else {
+ $sendsomething++;
+ }
+ }
+ } keys %to;
+
+ my %record=&Apache::lonnet::restore('_feedback');
+ my ($temp)=keys %record;
+ unless ($temp=~/^error\:/) {
+ my %newrecord=();
+ $newrecord{'resource'}=$feedurl;
+ $newrecord{'subnumber'}=$record{'subnumber'}+1;
+ unless (&Apache::lonnet::cstore(\%newrecord,'_feedback') eq 'ok') {
+ $status.='
Not registered
';
+ }
+ }
+
+ return ($status,$sendsomething);
+}
+
+sub adddiscuss {
+ my ($symb,$email,$anon)=@_;
+ my $status='';
+ if (&Apache::lonnet::allowed('pch',$ENV{'request.course.id'})) {
+
+ my %contrib=('message' => $email,
+ 'sendername' => $ENV{'user.name'},
+ 'senderdomain' => $ENV{'user.domain'});
+ if ($anon) {
+ $contrib{'anonymous'}='true';
+ }
+ if (($symb) && ($email)) {
+ $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'});
+ my %storenewentry=($symb => time);
+ $status.='
Updating discussion time: '.
+ &Apache::lonnet::put('discussiontimes',\%storenewentry,
+ $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
+ $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ }
+ my %record=&Apache::lonnet::restore('_discussion');
+ my ($temp)=keys %record;
+ unless ($temp=~/^error\:/) {
+ my %newrecord=();
+ $newrecord{'resource'}=$symb;
+ $newrecord{'subnumber'}=$record{'subnumber'}+1;
+ $status.='
Registering: '.
+ &Apache::lonnet::cstore(\%newrecord,'_discussion');
+ }
+ } else {
+ $status.='Failed.';
+ }
+ return $status.'
';
+}
+
+sub handler {
+ my $r = shift;
+ if ($r->header_only) {
+ $r->content_type('text/html');
+ $r->send_http_header;
+ return OK;
+ }
+
+# --------------------------- Get query string for limited number of parameters
+
+ map {
+ my ($name, $value) = split(/=/,$_);
+ $value =~ tr/+/ /;
+ $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
+ if (($name eq 'hide') || ($name eq 'unhide')) {
+ unless ($ENV{'form.'.$name}) {
+ $ENV{'form.'.$name}=$value;
+ }
+ }
+ } (split(/&/,$ENV{'QUERY_STRING'}));
+
+ if (($ENV{'form.hide'}) || ($ENV{'form.unhide'})) {
+# ----------------------------------------------------------------- Hide/unhide
+ $r->content_type('text/html');
+ $r->send_http_header;
+
+ my $entry=$ENV{'form.hide'}?$ENV{'form.hide'}:$ENV{'form.unhide'};
+
+ my ($symb,$idx)=split(/\:\:\:/,$entry);
+ my ($map,$ind,$url)=split(/\_\_\_/,$symb);
+
+ my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
+ $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
+ $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+
+
+ my $currenthidden=$contrib{'hidden'};
+
+ if ($ENV{'form.hide'}) {
+ $currenthidden.='.'.$idx.'.';
+ } else {
+ $currenthidden=~s/\.$idx\.//g;
+ }
+ my %newhash=('hidden' => $currenthidden);
+
+ &Apache::lonnet::store(\%newhash,$symb,$ENV{'request.course.id'},
+ $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
+ $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+
+ &redirect_back($r,'/res/'.$url,'Changed discussion status