--- loncom/interface/lonfeedback.pm 2001/02/08 21:35:24 1.5 +++ loncom/interface/lonfeedback.pm 2010/11/20 01:33:04 1.273.4.12 @@ -1,278 +1,4225 @@ # The LearningOnline Network # Feedback # -# (Internal Server Error Handler +# $Id: lonfeedback.pm,v 1.273.4.12 2010/11/20 01:33:04 raeburn Exp $ # -# (Login Screen -# 5/21/99,5/22,5/25,5/26,5/31,6/2,6/10,7/12,7/14, -# 1/14/00,5/29,5/30,6/1,6/29,7/1,11/9 Gerd Kortemeyer) +# Copyright Michigan State University Board of Trustees # -# 3/1/1 Gerd Kortemeyer) +# This file is part of the LearningOnline Network with CAPA (LON-CAPA). # -# 3/1,2/3,2/5,2/6,2/8 Gerd Kortemeyer +# LON-CAPA is free software; you can redistribute it and/or modify +# 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/ +# +### + package Apache::lonfeedback; use strict; use Apache::Constants qw(:common); 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 Apache::lonrss(); +use HTML::LCParser(); +use Apache::lonspeller(); +use Apache::longroup; +use Cwd; +use LONCAPA; -sub handler { - my $r = shift; - $r->content_type('text/html'); - $r->send_http_header; - return OK if $r->header_only; +sub discussion_open { + my ($status,$symb)=@_; +# Advanced roles can always discuss + if ($env{'request.role.adv'}) { return 1; } +# Get discussion closing date + my $close=&Apache::lonnet::EXT('resource.0.discussend',$symb); +# If it is defined and in the future, the instructor wants this discussion to be open + if (defined($close) && $close ne '' && $close > time) { + return 1; + } +# It was not explicitly open, check if the problem is available. +# If the problem is not available, close the discussion + if (defined($status) && + !($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER' + || $status eq 'OPEN')) { + return 0; + } +# The problem is available, but check if the instructor explictly closed discussion + if (defined($close) && $close ne '' && $close < time) { + return 0; + } + return 1; +} - my $feedurl=$ENV{'form.postdata'}; - $feedurl=~s/^http\:\/\///; - $feedurl=~s/^$ENV{'SERVER_NAME'}//; - $feedurl=~s/^$ENV{'HTTP_HOST'}//; +sub discussion_visible { + my ($status)=@_; + if (not &discussion_open($status)) { + my $hidden=&Apache::lonnet::EXT('resource.0.discusshide'); + if (lc($hidden) eq 'yes' or $hidden eq '' or !defined($hidden)) { + if (!$env{'request.role.adv'}) { return 0; } + } + } + return 1; +} - if ((($feedurl=~/^\/res/) && ($feedurl!~/^\/res\/adm/)) - || ($ENV{'request.course.id'})) { -# --------------------------------------------------- Print login screen header - unless ($ENV{'form.sendit'}) { - my $options=''; - if (($feedurl=~/^\/res/) && ($feedurl!~/^\/res\/adm/)) { - $options= - '
Feedback to resource author';
- }
- if ($ENV{'course.'.$ENV{'request.course.id'}.'.question.email'}) {
- $options.=
- '
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 ($options) {
- $r->print(<
'.&send_message_link($ressymb);
+ }
+ }
+ if ($group ne '' && $mode eq 'board') {
+ if (&check_group_priv($group,'vgb') ne 'ok') {
+ return '';
+ }
+ }
+
+ my ($blocked,$blocktext) =
+ &Apache::loncommon::blocking_status('boards');
+ if ($blocked) {
+ &Apache::lonenc::check_encrypt(\$ressymb);
+ if ($mode ne 'board') {
+ $blocktext.='
'.&send_message_link($ressymb);
+ }
+ return $blocktext;
+ }
+
+ my @bgcols = ("LC_disc_old_item","LC_disc_new_item");
+ 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;
+ my $encsymb=&Apache::lonenc::check_encrypt($ressymb);
+ my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
+ && ($ressymb=~/\.(problem|exam|quiz|assess|survey|form|task)$/));
+
+ my %usernamesort = ();
+ my %namesort =();
+ my %subjectsort = ();
+
+# Get discussion display settings for this discussion
+ my $lastkey = $ressymb.'_lastread';
+ my $showkey = $ressymb.'_showonlyunread';
+ my $markkey = $ressymb.'_showonlyunmark',
+ my $visitkey = $ressymb.'_visit';
+ my $ondispkey = $ressymb.'_markondisp';
+ my $userpickkey = $ressymb.'_userpick';
+ my $toggkey = $ressymb.'_readtoggle';
+ my $readkey = $ressymb.'_read';
+ $ressymb=$encsymb;
+ my %dischash = &Apache::lonnet::get('nohist_'.$cid.'_discuss',[$lastkey,$showkey,$markkey,$visitkey,$ondispkey,$userpickkey,$toggkey,$readkey],$env{'user.domain'},$env{'user.name'});
+ my %discinfo = ();
+ my $showonlyunread = 0;
+ my $showunmark = 0;
+ my $markondisp = 0;
+ my $prevread = 0;
+ my $previous = 0;
+ my $visit = 0;
+ my $newpostsflag = 0;
+ my @posters = split(/\&/,$dischash{$userpickkey});
+
+# 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','grouppick','totposters']);
+ my $sortposts = $env{'form.sortposts'};
+ my $statusfilter = $env{'form.statusfilter'};
+ my @sectionpick = split(/,/,$env{'form.sectionpick'});
+ my @grouppick = split(/,/,$env{'form.grouppick'});
+ my @rolefilter = split(/,/,$env{'form.rolefilter'});
+
+ my $totposters = $env{'form.totposters'};
+ $previous = $env{'form.previous'};
+ if ($previous > 0) {
+ $prevread = $previous;
+ } elsif (defined($dischash{$lastkey})) {
+ unless ($dischash{$lastkey} eq '') {
+ $prevread = $dischash{$lastkey};
+ }
+ }
+
+ my $cdom = $env{'course.'.$cid.'.domain'};
+ my $cnum = $env{'course.'.$cid.'.num'};
+ my $crstype = &Apache::loncommon::course_type();
+
+
+# Get information about students and non-students in course for filtering display of posts
+ my %roleshash = ();
+ my %roleinfo = ();
+ my ($classgroups,$studentgroups);
+ if ($env{'form.rolefilter'}) {
+ %roleshash = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);
+ foreach my $rolekey (keys(%roleshash)) {
+ my ($role,$uname,$udom,$sec) = split(/:/,$rolekey);
+ if ($role =~ /^cr/) {
+ $role = 'cr';
+ }
+ my ($end,$start) = split(/:/,$roleshash{$rolekey});
+ my $now = time;
+ my $status = 'Active';
+ if (($now < $start) || ($end > 0 && $now > $end)) {
+ $status = 'Expired';
+ }
+ if ($uname && $udom) {
+ push(@{$roleinfo{$uname.':'.$udom}}, $role.':'.$sec.':'.$status);
+ }
+ }
+ my ($classlist,$keylist) =
+ &Apache::loncoursedata::get_classlist($cdom,$cnum);
+ my $sec_index = &Apache::loncoursedata::CL_SECTION();
+ my $status_index = &Apache::loncoursedata::CL_STATUS();
+ while (my ($student,$data) = each %$classlist) {
+ my ($section,$status) = ($data->[$sec_index],
+ $data->[$status_index]);
+ push(@{$roleinfo{$student}}, 'st:'.$section.':'.$status);
+ }
+ ($classgroups,$studentgroups) =
+ &Apache::loncoursedata::get_group_memberships($classlist,$keylist,
+ $cdom,$cnum);
+ }
+
+# Get discussion display default settings for user
+ if ($env{'environment.discdisplay'} eq 'unread') {
+ $showonlyunread = 1;
+ }
+ if ($env{'environment.discmarkread'} eq 'ondisp') {
+ $markondisp = 1;
+ }
+
+# Override user's default if user specified display setting for this discussion
+ if (defined($dischash{$ondispkey})) {
+ unless ($dischash{$ondispkey} eq '') {
+ $markondisp = $dischash{$ondispkey};
+ }
+ }
+ if ($markondisp) {
+ $discinfo{$lastkey} = time;
+ }
+
+ if (defined($dischash{$showkey})) {
+ unless ($dischash{$showkey} eq '') {
+ $showonlyunread = $dischash{$showkey};
+ }
+ }
+
+ if (defined($dischash{$markkey})) {
+ unless ($dischash{$markkey} eq '') {
+ $showunmark = $dischash{$markkey};
+ }
+ }
+
+ if (defined($dischash{$visitkey})) {
+ unless ($dischash{$visitkey} eq '') {
+ $visit = $dischash{$visitkey};
+ }
+ }
+ $visit ++;
+
+ my $seeid;
+ if (($group ne '') && ($mode eq 'board') &&
+ ($ressymb =~ m|^bulletin___\d+___adm/wrapper/adm/\Q$cdom\E/\Q$cnum\E/\d+/bulletinboard$|)) {
+ if (&check_group_priv($group,'dgp') eq 'ok') {
+ $seeid = 1;
+ }
+ } else {
+ $seeid=&Apache::lonnet::allowed('rin',$crs);
+ }
+ my @discussionitems=();
+ my %shown = ();
+ my @posteridentity=();
+
+ my $current=0;
+ my $visible=0;
+ my @depth=();
+ my @replies = ();
+ my %alldiscussion=();
+ my %imsitems=();
+ my %imsfiles=();
+ my %notshown = ();
+ my %newitem = ();
+ my $maxdepth=0;
+ my %anonhash=();
+ my $anoncnt=0;
+ my $target='';
+ unless ($env{'browser.interface'} eq 'textual' ||
+ $env{'environment.remote'} eq 'off' ) {
+ $target='target="LONcom"';
+ }
+
+ my $now = time;
+ $discinfo{$visitkey} = $visit;
+
+ &Apache::lonnet::put('nohist_'.$cid.'_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,\@grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,\%anonhash,$anoncnt,$group);
+
+ my $discussion='';
+ my $manifestfile;
+ my $manifestok=0;
+ my $tempexport;
+ my $imsresources;
+ my $copyresult;
+
+ my $function = &Apache::loncommon::get_users_function();
+ my $color = &Apache::loncommon::designparm($function.'.tabbg',
+ $env{'user.domain'});
+ my %lt = &Apache::lonlocal::texthash(
+ 'cuse' => 'Current discussion settings',
+ 'allposts' => 'All posts',
+ 'unread' => 'New posts only',
+ 'unmark' => 'Unread only',
+ 'ondisp' => 'Once displayed',
+ 'onmark' => 'Once marked not NEW',
+ 'toggoff' => 'Off',
+ 'toggon' => 'On',
+ 'disa' => 'Posts to be displayed',
+ 'npce' => 'Posts cease to be marked "NEW"',
+ 'epcb' => 'Each post can be toggled read/unread',
+ 'chgt' => 'Change',
+ 'disp' => 'Display',
+ 'nolo' => 'Not new',
+ 'togg' => 'Toggle read/unread',
+ 'aner' => 'An error occurred opening the manifest file.',
+ 'difo' => 'Discussion for',
+ 'aerr' => 'An error occurred opening the export file for posting',
+ 'aysu' => 'Are you sure you want to delete this post?',
+ 'dpwn' => 'Deleted posts will no longer be visible to you and other students',
+ 'bwco' => 'but will continue to be visible to your instructor',
+ 'depo' => 'Deleted posts will no longer be visible to you or anyone else.',
+ );
+
+ my $currdisp = $lt{'allposts'};
+ my $currmark = $lt{'onmark'};
+ my $currtogg = $lt{'toggoff'};
+ my $dispchange = $lt{'unread'};
+ my $markchange = $lt{'ondisp'};
+ my $toggchange = $lt{'toggon'};
+ my $chglink = '/adm/feedback?modifydisp='.$ressymb;
+ my $displinkA = 'onlyunread';
+ my $displinkB = 'onlyunmark';
+ my $marklink = 'markondisp';
+ my $togglink = 'toggon';
+
+ if ($markondisp) {
+ $currmark = $lt{'ondisp'};
+ $markchange = $lt{'onmark'};
+ $marklink = 'markonread';
+ }
+
+ if ($showonlyunread) {
+ $currdisp = $lt{'unread'};
+ $dispchange = $lt{'allposts'};
+ $displinkA = 'allposts';
+ }
+
+ if ($showunmark) {
+ $currdisp = $lt{'unmark'};
+ $dispchange = $lt{'unmark'};
+ $displinkA='allposts';
+ $displinkB='onlyunread';
+ $showonlyunread = 0;
+ }
+
+ if ($dischash{$toggkey}) {
+ $currtogg = $lt{'toggon'};
+ $toggchange = $lt{'toggoff'};
+ $togglink = 'toggoff';
+ }
+
+ $chglink .= '&changes='.$displinkA.'_'.$displinkB.'_'.$marklink.'_'.$togglink;
+
+ if ($newpostsflag) {
+ $chglink .= '&previous='.$prevread;
+ }
+ $chglink.=&group_args($group);
+
+ if ($visible) {
+# Print the discusssion
+ if ($outputtarget eq 'tex') {
+ $discussion.='
';
+ }
+ } else {
+ my $colspan=$maxdepth+1;
+ $discussion.= qq|
+ |;
+ $discussion.='