--- loncom/interface/lonfeedback.pm 2004/04/28 23:59:53 1.79
+++ loncom/interface/lonfeedback.pm 2007/10/26 20:51:43 1.251
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Feedback
#
-# $Id: lonfeedback.pm,v 1.79 2004/04/28 23:59:53 raeburn Exp $
+# $Id: lonfeedback.pm,v 1.251 2007/10/26 20:51:43 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -34,484 +34,2578 @@ use Apache::Constants qw(:common);
use Apache::lonmsg();
use Apache::loncommon();
use Apache::lontexconvert();
-use Apache::lonlocal;
+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 discussion_open {
+ my ($status,$symb)=@_;
+ if ($env{'request.role.adv'}) { return 1; }
+ if (defined($status) &&
+ !($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
+ || $status eq 'OPEN')) {
+ return 0;
+ }
+ my $close=&Apache::lonnet::EXT('resource.0.discussend',$symb);
+ if (defined($close) && $close ne '' && $close < time) {
+ return 0;
+ }
+ return 1;
+}
+
+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;
+}
sub list_discussion {
- my ($mode,$status,$symb)=@_;
-# &Apache::lonnet::logthis("status is $status");
- if (!($status eq 'CAN_ANSWER' || $status eq 'CANNOT_ANSWER'
- || $status eq 'OPEN')) {
- return '';
+ my ($mode,$status,$ressymb,$imsextras,$group)=@_;
+ unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); }
+ unless ($ressymb) { return ''; }
+ $ressymb=&wrap_symb($ressymb);
+ 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)) {
+ if ($mode ne 'board') {
+ &Apache::lonenc::check_encrypt(\$ressymb);
+ return '
'.&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 = ("#cccccc","#eeeeee");
my $discussiononly=0;
if ($mode eq 'board') { $discussiononly=1; }
- unless ($ENV{'request.course.id'}) { return ''; }
- my $crs='/'.$ENV{'request.course.id'};
- if ($ENV{'request.course.sec'}) {
- $crs.='_'.$ENV{'request.course.sec'};
- }
+ 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();
+ 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};
+ }
}
- unless ($symb) { return ''; }
- my %dischash = &Apache::lonnet::restore($symb,'nohist_'.$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'});
- my %readids = ();
- my $showonlyunread;
- my $prevread = 0;
+ my $cdom = $env{'course.'.$cid.'.domain'};
+ my $cnum = $env{'course.'.$cid.'.num'};
- foreach my $key (keys %dischash) {
- if ($key eq 'lastread') {
- $prevread = $dischash{$key};
- }
- if ($key eq 'showonlyunread') {
- $showonlyunread = $dischash{$key};
- } else {
- if ($dischash{$key} eq 'read') {
- $readids{$key} = 1;
+# 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);
}
- my $seeid=&Apache::lonnet::allowed('rin',$crs);
- my $viewgrades=(&Apache::lonnet::allowed('vgr',$crs)
- && ($symb=~/\.(problem|exam|quiz|assess|survey|form)$/));
+# 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=();
- # backward compatibility (bulletin boards used to be 'wrapped')
- my $ressymb=$symb;
- if ($mode eq 'board') {
- $ressymb=~s|(bulletin___\d+___)|$1adm/wrapper|;
- }
- my %contrib=&Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+ my %shown = ();
+ my @posteridentity=();
+
+ my $current=0;
my $visible=0;
my @depth=();
- my @original=();
- my @index=();
- my @replies=();
+ 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' ) {
+ unless ($env{'browser.interface'} eq 'textual' ||
+ $env{'environment.remote'} eq 'off' ) {
$target='target="LONcom"';
}
-
+
my $now = time;
- my %discinfo = (
- 'lastread' => $now,
- );
- &Apache::lonnet::cstore(\%discinfo,$symb,'nohist_'.$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'});
+ $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.='{\tiny \vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}'.
+ '\textbf{DISCUSSIONS}\makebox[2 cm][b]{\hrulefill}'.
+ '\vskip 0 mm\noindent\textbf{'.$lt{'cuse'}.'}:\vskip 0 mm'.
+ '\noindent\textbf{'.$lt{'disa'}.'}: \textit{'.$currdisp.'}\vskip 0 mm'.
+ '\noindent\textbf{'.$lt{'npce'}.'}: \textit{'.$currmark.'}}';
+ } elsif ($outputtarget eq 'export') {
+# Create temporary directory if this is an export
+ my $now = time;
+ if ((defined($imsextras)) && ($$imsextras{'caller'} eq 'imsexport')) {
+ $tempexport = $$imsextras{'tempexport'};
+ if (!-e $tempexport) {
+ mkdir($tempexport,0700);
+ }
+ $tempexport .= '/'.$$imsextras{'count'};
+ if (!-e $tempexport) {
+ mkdir($tempexport,0700);
+ }
+ } else {
+ $tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports';
+ if (!-e $tempexport) {
+ mkdir($tempexport,0700);
+ }
+ $tempexport .= '/'.$now;
+ if (!-e $tempexport) {
+ mkdir($tempexport,0700);
+ }
+ $tempexport .= '/'.$env{'user.domain'}.'_'.$env{'user.name'};
+ }
+ if (!-e $tempexport) {
+ mkdir($tempexport,0700);
+ }
+# open manifest file
+ my $manifest = '/imsmanifest.xml';
+ my $manifestfilename = $tempexport.$manifest;
+ if ($manifestfile = Apache::File->new('>'.$manifestfilename)) {
+ $manifestok=1;
+ print $manifestfile qq|
+
+
+
+
+ $lt{'difo'} $ressymb\n|;
+ } else {
+ $discussion .= $lt{'aner'}.'
';
+ }
+ } else {
+ my $colspan=$maxdepth+1;
+ $discussion.= qq|
+
+ |;
+ $discussion.='
';
+ $$alldiscussion{$thisindex}=$idx;
+ $$shown{$idx} = 0;
+ $index[$idx]=$thisindex;
+ }
+ if ($outputtarget eq 'export') {
+ %{$$imsitems{$idx}} = ();
+ $$imsitems{$idx}{'isvisible'}='true';
+ if ($hidden) {
+ $$imsitems{$idx}{'isvisible'}='false';
+ }
+ $$imsitems{$idx}{'title'}=$subjects{$numoldver};
+ $$imsitems{$idx}{'message'}=$messages{$numoldver};
+ $$imsitems{$idx}{'attach'}=$attachtxt{$numoldver};
+ $$imsitems{$idx}{'timestamp'}=$contrib{$idx.':timestamp'};
+ $$imsitems{$idx}{'sender'}=$plainname.' ('.
+ $contrib{$idx.':sendername'}.' at '.
+ $contrib{$idx.':senderdomain'}.')';
+ $$imsitems{$idx}{'isanonymous'}='false';
+ if ($contrib{$idx.':anonymous'}) {
+ $$imsitems{$idx}{'isanonymous'}='true';
+ }
+ $$imsitems{$idx}{'currversion'}=$numoldver;
+ %{$$imsitems{$idx}{'allattachments'}}=%allattachments;
+ unless ($messages{$numoldver} eq '' && $attachtxt{$numoldver} eq '') {
+ $$shown{$idx} = 1;
+ }
+ } else {
+ if ($message) {
+ my $spansize = 2;
+ if ($showonlyunread && $prevread > $posttime) {
+ $$notshown{$idx} = 1;
+ } elsif ($showunmark && $$dischash{$readkey}=~/\.$idx\./) {
+ $$notshown{$idx} = 1;
+ } else {
+# apply filters
+ my $uname = $contrib{$idx.':sendername'};
+ my $udom = $contrib{$idx.':senderdomain'};
+ my $poster = $uname.':'.$udom;
+ if ($env{'form.totposters'} ne '') {
+ if ($totposters == 0) {
+ $$shown{$idx} = 0;
+ } elsif ($totposters > 0) {
+ if (grep/^$poster$/,@{$posters}) {
+ $$shown{$idx} = 1;
+ }
+ }
+ } elsif ($sortposts) {
+ if ($skiptest) {
+ $$shown{$idx} = 1;
+ } else {
+ foreach my $role (@{$$roleinfo{$poster}}) {
+ if ($role =~ /^cc:/) {
+ my $cc_regexp = $roleregexp.':[^:]*:'.$statusregexp;
+ if ($role =~ /$cc_regexp/) {
+ $$shown{$idx} = 1;
+ last;
+ }
+ } elsif ($role =~ /^$rolematch$/) {
+ $$shown{$idx} = 1;
+ last;
+ }
+ }
+ }
+ if ($$shown{$idx} && !$skip_group_check) {
+ my $showflag = 0;
+ if (ref($$classgroups{$poster}{active}) eq 'HASH') {
+ foreach my $grp (@{$grouppick}) {
+ if (grep/^\Q$grp\E$/,
+ keys(%{$$classgroups{$poster}{active}})) {
+ $showflag = 1;
+ last;
+ }
+ }
+ }
+ if ($showflag) {
+ $$shown{$idx} = 1;
+ } else {
+ $$shown{$idx} = 0;
+ }
+ }
+ } else {
+ $$shown{$idx} = 1;
+ }
+ }
+ unless ($$notshown{$idx} == 1) {
+ if ($prevread > 0 && $prevread <= $posttime) {
+ $$newitem{$idx} = 1;
+ $$discussionitems[$idx] .= '
+
+ NEW | ';
+ } else {
+ $$newitem{$idx} = 0;
+ $$discussionitems[$idx] .= '
+
+ | ';
+ }
+ $$discussionitems[$idx] .= ' '.
+ ''.$subject.' '.
+ $sender.' '.$vgrlink.' ('.
+ &Apache::lonlocal::locallocaltime($posttime).') | ';
+ if ($$dischash{$toggkey}) {
+ $$discussionitems[$idx].=' '.
+ $ctlink.' | ';
+ }
+ $$discussionitems[$idx].= '
'.
+ $message.'
';
+ if ($contrib{$idx.':history'}) {
+ my @postversions = ();
+ $$discussionitems[$idx] .= &mt('This post has been edited by the author.');
+ if ($seeid) {
+ $$discussionitems[$idx] .= ' '.&mt('Display all versions').'';
+ }
+ $$discussionitems[$idx].='
'.&mt('Earlier version(s) were posted on: ');
+ if ($contrib{$idx.':history'} =~ m/:/) {
+ @postversions = split(/:/,$contrib{$idx.':history'});
+ } else {
+ @postversions = ("$contrib{$idx.':history'}");
+ }
+ for (my $i=0; $i<@postversions; $i++) {
+ my $version = $i+1;
+ $$discussionitems[$idx] .= ''.$version.'. - '.&Apache::lonlocal::locallocaltime($postversions[$i]).' ';
+ }
+ }
+ }
}
}
}
}
}
- my $discussion='';
- if ($visible) {
-# Print a the discusssion
- $discussion .= '';
+ if (defined($statusfilter) && $statusfilter ne '') {
+ if ($statusfilter eq 'all') {
+ $statusregexp = '[^:]+';
+ } else {
+ $statusregexp = $statusfilter;
+ $skiptest = 0;
+ }
}
- if ($discussiononly) {
- $discussion.=(<
-
-
-
-
-
-Note: in anonymous discussion, your name is visible only to
-course faculty
-Title:
-
-
-Attachment (128 KB max size):
-
-
-ENDDISCUSS
- $discussion.=&generate_preview_button();
+ return ($skiptest,$roleregexp,$secregexp,$statusregexp);
+}
+
+
+sub get_post_contents {
+ my ($contrib,$idx,$seeid,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$numver) = @_;
+ my $discussion = '';
+ my $start=$numver;
+ my $end=$numver + 1;
+ %{$$imsfiles{$idx}}=();
+ if ($type eq 'allversions') {
+ unless($seeid) {
+ $discussion=&mt('You do not have privileges to view all versions of posts.').' '.&mt('Please select a different role.');
+ return $discussion;
+ }
+ }
+# $$screenname=&Apache::loncommon::screenname(
+# $$contrib{$idx.':sendername'},
+# $$contrib{$idx.':senderdomain'});
+ $$plainname=&Apache::loncommon::nickname(
+ $$contrib{$idx.':sendername'},
+ $$contrib{$idx.':senderdomain'});
+ $$screenname=$$contrib{$idx.':screenname'};
+
+ my $sender=&Apache::loncommon::aboutmewrapper(
+ $$plainname,
+ $$contrib{$idx.':sendername'},
+ $$contrib{$idx.':senderdomain'}).' ('.
+ $$contrib{$idx.':sendername'}.' at '.
+ $$contrib{$idx.':senderdomain'}.')';
+ my $attachmenturls = $$contrib{$idx.':attachmenturl'};
+ my @postversions = ();
+ if ($type eq 'allversions' || $type eq 'export') {
+ $start = 0;
+ if ($$contrib{$idx.':history'}) {
+ @postversions = split(/:/,$$contrib{$idx.':history'});
+ }
+ &get_post_versions($messages,$$contrib{$idx.':message'},1);
+ &get_post_versions($subjects,$$contrib{$idx.':subject'},1);
+ push(@postversions,$$contrib{$idx.':timestamp'});
+ $end = @postversions;
} else {
- if (&Apache::lonnet::allowed('pch',
- $ENV{'request.course.id'}.
- ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
- $discussion.='';
- }
+ &get_post_versions($messages,$$contrib{$idx.':message'},1,$numver);
+ &get_post_versions($subjects,$$contrib{$idx.':subject'},1,$numver);
+ }
+
+ if ($$contrib{$idx.':anonymous'}) {
+ $sender.=' ['.&mt('anonymous').'] '.$$screenname;
}
- return $discussion;
+ if ($type eq 'allversions') {
+ $discussion=(''.$sender.'
');
+ }
+ for (my $i=$start; $i<$end; $i++) {
+ my ($timesent,$attachmsg);
+ my %currattach = ();
+ $timesent = &Apache::lonlocal::locallocaltime($postversions[$i]);
+ &newline_to_br(\$messages->{$i});
+ $$messages{$i}=&Apache::lontexconvert::msgtexconverted($$messages{$i});
+ $$subjects{$i}=~s/\n/\
/g;
+ $$subjects{$i}=&Apache::lontexconvert::msgtexconverted($$subjects{$i});
+ if ($attachmenturls) {
+ &extract_attachments($attachmenturls,$idx,$i,\$attachmsg,$allattachments,\%currattach);
+ }
+ if ($type eq 'export') {
+ $$imsfiles{$idx}{$i} = '';
+ if ($attachmsg) {
+ $$attachtxt{$i} = '
'.&mt('Attachments').':
';
+ foreach my $key (sort(keys(%currattach))) {
+ if ($$allattachments{$key}{'filename'} =~ m-^/uploaded/([^/]+/[^/]+)(/feedback)?(/?\d*)/([^/]+)$-) {
+ my $fname = $1.$3.'/'.$4;
+ $$imsfiles{$idx}{$i} .= ''."\n";
+ $$attachtxt{$i}.= ''.$4.'
';
+ }
+ }
+ }
+ } else {
+ if ($attachmsg) {
+ $$attachtxt{$i} = '
'.&mt('Attachments').':'.$attachmsg.'
';
+ } else {
+ $$attachtxt{$i} = '';
+ }
+ }
+ if ($type eq 'allversions') {
+ $discussion.= <<"END";
+- $$subjects{$i}, $timesent
+$$messages{$i}
+$$attachtxt{$i}
+END
+ }
+ }
+ if ($type eq 'allversions') {
+ $discussion.='
';
+ return $discussion;
+ } else {
+ return;
+ }
+}
+
+sub replicate_attachments {
+ my ($attachrefs,$tempexport) = @_;
+ my $response;
+ foreach my $id (keys(%{$attachrefs})) {
+ if ($$attachrefs{$id}{'filename'} =~ m-^/uploaded/([^/]+)/([^/]+)(/feedback)?(/?\d*)/([^/]+)$-) {
+ my $path = $tempexport;
+ my $tail = $1.'/'.$2.$4;
+ my @extras = split(/\//,$tail);
+ my $destination = $tempexport.'/'.$1.'/'.$2.$4.'/'.$5;
+ if (!-e $destination) {
+ my $i= 0;
+ while ($i<@extras) {
+ $path .= '/'.$extras[$i];
+ if (!-e $path) {
+ mkdir($path,0700);
+ }
+ $i ++;
+ }
+ my ($content,$rtncode);
+ my $uploadreply = &Apache::lonnet::getuploaded('GET',$$attachrefs{$id}{'filename'},$1,$2,$content,$rtncode);
+ if ($uploadreply eq 'ok') {
+ my $attachcopy;
+ if ($attachcopy = Apache::File->new('>'.$destination)) {
+ print $attachcopy $content;
+ close($attachcopy);
+ } else {
+ $response .= &mt('Error copying file attachment - [_1] to IMS package',$5).': '.$!.'
'."\n";
+ }
+ } else {
+ &Apache::lonnet::logthis("Replication of attachment failed when building IMS export of discussion posts - domain: $1, course: $2, file: $$attachrefs{$id}{'filename'} -error: $rtncode");
+ $response .= &mt('Error copying file attachment - [_1] to IMS package: ',$5).$rtncode.'
'."\n";
+ }
+ }
+ }
+ }
+ return $response;
}
sub mail_screen {
- my ($r,$feedurl,$options) = @_;
- my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion',
- '','onLoad="window.focus();"');
- my $title=&Apache::lonnet::gettitle($feedurl);
- if (!$title) { $title = $feedurl; }
+ my ($r,$feedurl,$options,$caller_symb) = @_;
+ if (exists($env{'form.origpage'})) {
+ &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','currnewattach','addnewattach','deloldattach','delnewattach','timestamp','idx','anondiscuss','discuss','blog','group','ref']);
+ }
+
+ my %lt = &Apache::lonlocal::texthash(
+ 'plch' => 'Please check at least one of the following feedback types:',
+ 'myqu' => 'My question/comment/feedback:',
+ 'title' => 'Title',
+ 'reta' => 'Retained attachments',
+ 'atta' => 'Attachment (128 KB max size)',
+ );
+ my $restitle = &get_resource_title($caller_symb,$feedurl);
my $quote='';
my $subject = '';
- if ($ENV{'form.replydisc'}) {
- my ($symb,$idx)=split(/\:\:\:/,$ENV{'form.replydisc'});
- my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
- $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
- unless (($contrib{'hidden'}=~/\.$idx\./) || ($contrib{'deleted'}=~/\.$idx\./)) {
- my $message=$contrib{$idx.':message'};
- $message=~s/\n/\
/g;
- $quote=''.&Apache::lontexconvert::msgtexconverted($message).'
';
- if ($idx > 0) {
- $subject = 'Re: '.$contrib{$idx.':subject'};
+ my $comment = '';
+ my $prevtag = '';
+ my $parentmsg = '';
+ my ($symb,$idx,$attachmenturls);
+ my $numoldver = 0;
+ my $attachmsg = '';
+ my $newattachmsg = '';
+ my @currnewattach = ();
+ my @currdelold = ();
+ my @keepold = ();
+ my %attachments = ();
+ my %currattach = ();
+ my $attachnum = 0;
+ my $anonchk = (< 0) {
+ my %msgversions = ();
+ &get_post_versions(\%msgversions,$contrib{$idx.':message'},0,$numoldver);
+ $quote = $msgversions{$numoldver};
+ }
+ if ($idx > 0) {
+ my %subversions = ();
+ &get_post_versions(\%subversions,$contrib{$idx.':subject'},1,$numoldver);
+ $subject = &mt('Re: ').$subversions{$numoldver};
+ }
+ $subject = &HTML::Entities::encode($subject,'<>&"');
+ } else {
+ $attachmenturls = $contrib{$idx.':attachmenturl'};
+ if ($idx > 0) {
+ my %msgversions = ();
+ &get_post_versions(\%msgversions,$contrib{$idx.':message'},0,$numoldver);
+ $comment = $msgversions{$numoldver};
+ my %subversions = ();
+ &get_post_versions(\%subversions,$contrib{$idx.':subject'},0,$numoldver);
+ $subject = $subversions{$numoldver};
+ }
+ if (defined($contrib{$idx.':replyto'})) {
+ $parentmsg = $contrib{$idx.':replyto'};
+ }
+ unless (exists($env{'form.origpage'})) {
+ my $anonflag = 'nonanon';
+ if ($contrib{$idx.':anonymous'}) {
+ $anonflag = 'anon';
+ }
+ $anonscript = (<';
}
}
- my $latexHelp = Apache::loncommon::helpLatexCheatsheet();
+
+ if ($env{'form.origpage'}) {
+ $subject = &unescape($env{'form.subject'});
+ $comment = &unescape($env{'form.comment'});
+ &process_attachments(\@currnewattach,\@currdelold,\@keepold);
+ }
+ my $latexHelp=&Apache::loncommon::helpLatexCheatsheet();
my $send=&mt('Send');
- $r->print(<
-
-The LearningOnline Network with CAPA
-
+ my $alert = &mt('Please select a feedback type.');
+ my $js= <
//
-
-$bodytag
-$title
+END
+
+ my %onload = ('onload' => 'window.focus();setposttype();');
+ my $start_page=
+ &Apache::loncommon::start_page('Resource Feedback and Discussion',$js,
+ {'add_entries' => \%onload});
+
+ if ($quote ne '') {
+ &newline_to_br(\$quote);
+ $quote=''.&Apache::lontexconvert::msgtexconverted($quote).'
';
+ }
+
+ $r->print(<$restitle
-ENDDOCUMENT
-$r->print(&generate_preview_button().'