'.
- '';
- if ($visible>2) {
- $discussion.=''.
- ''.&mt('Threaded View').' '.
- ''.&mt('Chronological View').'
- '.
+ "\n".'';
+ $discussion .= &action_links_bar($colspan,$ressymb,$visible,
+ $newpostsflag,$group,
+ $prevread,$markondisp);
+ my $escsymb=&escape($ressymb);
+ my $numhidden = keys(%notshown);
+ if ($numhidden > 0) {
+ my $colspan = $maxdepth+1;
+ $discussion.="\n".''.
+ ''.&mt('Sorting/Filtering options').'  ';
- } else {
- $discussion .= ' | ';
- }
- $discussion .=''.&mt('Export').'? | ';
- if ($newpostsflag) {
- if (!$markondisp) {
- $discussion .=''.&mt('Mark NEW posts no longer new').' ';
- } else {
- $discussion .= ' | | ';
- }
- } else {
- $discussion .= ' | ';
- }
- $discussion .= ' | ';
- } else {
- $discussion.='\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.'}';
- }
- my $numhidden = keys %notshown;
- if ($numhidden > 0) {
- my $colspan = $maxdepth+1;
- $discussion.="\n".''.
- ''.&mt('Show all posts').' '.&mt('to display').' '.
+ $discussion .= &group_args($group);
+ $discussion .= '">'.&mt('Show all posts').' '.&mt('to display').' '.
$numhidden.' ';
- if ($showunmark) {
- $discussion .= &mt('posts previously marked read');
- } else {
- $discussion .= &mt('previously viewed posts');
+ if ($showunmark) {
+ $discussion .= &mt('posts previously marked read');
+ } else {
+ $discussion .= &mt('previously viewed posts');
+ }
+ $discussion .= '
| ';
}
- $discussion .= ' ';
}
# Choose sort mechanism
my @showposts = ();
if ($sortposts eq 'descdate') {
- @showposts = (sort { $b <=> $a } keys %alldiscussion);
+ @showposts = (sort { $b <=> $a } keys(%alldiscussion));
} elsif ($sortposts eq 'thread') {
- @showposts = (sort { $a <=> $b } keys %alldiscussion);
+ @showposts = (sort { $a <=> $b } keys(%alldiscussion));
} elsif ($sortposts eq 'subject') {
- foreach (sort keys %subjectsort) {
- push @showposts, @{$subjectsort{$_}};
+ foreach my $key (sort(keys(%subjectsort))) {
+ push(@showposts, @{$subjectsort{$key}});
}
} elsif ($sortposts eq 'username') {
- foreach my $domain (sort keys %usernamesort) {
- foreach (sort keys %{$usernamesort{$domain}}) {
- push @showposts, @{$usernamesort{$domain}{$_}};
+ foreach my $domain (sort(keys(%usernamesort))) {
+ foreach my $key (sort(keys(%{$usernamesort{$domain}}))) {
+ push(@showposts, @{$usernamesort{$domain}{$key}});
}
}
} elsif ($sortposts eq 'lastfirst') {
- foreach my $last (sort keys %namesort) {
- foreach (sort keys %{$namesort{$last}}) {
- push @showposts, @{$namesort{$last}{$_}};
+ foreach my $last (sort(keys(%namesort))) {
+ foreach my $key (sort(keys(%{$namesort{$last}}))) {
+ push(@showposts, @{$namesort{$last}{$key}});
}
}
} else {
- $sortposts = 'ascdate';
- @showposts = (sort { $a <=> $b } keys %alldiscussion);
+ @showposts = (sort { $a <=> $b } keys(%alldiscussion));
}
- foreach (@showposts) {
- unless (($sortposts eq 'thread') || ($sortposts eq 'ascdate' && $ENV{'environment.threadeddiscussion'})) {
- $alldiscussion{$_} = $_;
+ my $currdepth = 0;
+ my $firstidx = $alldiscussion{$showposts[0]};
+ foreach my $post (@showposts) {
+ unless (($sortposts eq 'thread') || (($sortposts eq '') && ($env{'environment.threadeddiscussion'})) || ($outputtarget eq 'export')) {
+ $alldiscussion{$post} = $post;
}
- unless ( ($notshown{$alldiscussion{$_}} eq '1') || ($shown{$alldiscussion{$_}} == 0) ) {
- if ($outputtarget ne 'tex') {
+ unless ( ($notshown{$alldiscussion{$post}} eq '1') || ($shown{$alldiscussion{$post}} == 0) ) {
+ if ($outputtarget ne 'tex' && $outputtarget ne 'export') {
$discussion.="\n";
- } else {
- $discussion.='\vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}';
}
- my $thisdepth=$depth[$alldiscussion{$_}];
- if ($outputtarget ne 'tex') {
+ my $thisdepth=$depth[$alldiscussion{$post}];
+ if ($outputtarget ne 'tex' && $outputtarget ne 'export') {
for (1..$thisdepth) {
$discussion.=' | ';
}
}
my $colspan=$maxdepth-$thisdepth+1;
- if ($outputtarget ne 'tex') {
- $discussion.=''.
- $discussionitems[$alldiscussion{$_}].
- ' | ';
- } else {
+ if ($outputtarget eq 'tex') {
#cleanup block
- $discussionitems[$alldiscussion{$_}]=~s/]*)>//;
- $discussionitems[$alldiscussion{$_}]=~s/]*)>]*)>/ | /;
+ $discussionitems[$alldiscussion{$post}]=~s/]*)>//;
+ $discussionitems[$alldiscussion{$post}]=~s/]*)>]*)>/ | /;
my $threadinsert='';
if ($thisdepth > 0) {
$threadinsert=' Reply: '.$thisdepth.'';
}
- $discussionitems[$alldiscussion{$_}]=~s/<\/td> | ]*)>/$threadinsert<\/td> | /;
- $discussionitems[$alldiscussion{$_}]=~s/]+)>(Edit|Hide|Delete|Reply|Submissions)<\/a>//g;
- $discussionitems[$alldiscussion{$_}]=~s/(|<\/b>|<\/a>|]+)>)//g;
-
- #FIXME xmlparse can't be safely called from inside xmlparse
- # due to the global variables that are use, the safe
- # space etc. I expect this has unforseen issues that
- # need resolving.
-
- $discussion.=&Apache::lonxml::xmlparse('','tex',$discussionitems[$alldiscussion{$_}]);
- }
+ $discussionitems[$alldiscussion{$post}]=~s/<\/td> | ]*)>/$threadinsert<\/td> | /;
+ $discussionitems[$alldiscussion{$post}]=~s/]+)>(Edit|Hide|Delete|Reply|Submissions)<\/a>//g;
+ $discussionitems[$alldiscussion{$post}]=~s/(|<\/b>|<\/a>|]+)>)//g;
+
+ $discussionitems[$alldiscussion{$post}]='\vskip 0 mm\noindent\makebox[2 cm][b]{\hrulefill}'.$discussionitems[$alldiscussion{$post}];
+ $discussion.=$discussionitems[$alldiscussion{$post}];
+ } elsif ($outputtarget eq 'export') {
+ my $postfilename = $alldiscussion{$post}.'-'.$imsitems{$alldiscussion{$post}}{'timestamp'}.'.html';
+ if ($manifestok) {
+ if (($depth[$alldiscussion{$post}] <= $currdepth) && ($alldiscussion{$post} != $firstidx)) {
+ print $manifestfile ' '."\n";
+ }
+ $currdepth = $depth[$alldiscussion{$post}];
+ print $manifestfile "\n".
+ '- '.
+ ''.$imsitems{$alldiscussion{$post}}{'title'}.'
';
+ $imsresources .= "\n".
+ ''."\n".
+ ''."\n".
+ $imsfiles{$alldiscussion{$post}}{$imsitems{$alldiscussion{$post}}{'currversion'}}.''."\n".
+ '';
+ }
+ my $postingfile;
+ my $postingfilename = $tempexport.'/'.$postfilename;
+ if ($postingfile = Apache::File->new('>'.$postingfilename)) {
+ print $postingfile 'Discussion Post'.
+ $imsitems{$alldiscussion{$post}}{'title'}.' '.
+ $imsitems{$alldiscussion{$post}}{'sender'}.
+ $imsitems{$alldiscussion{$post}}{'timestamp'}.'
'.
+ $imsitems{$alldiscussion{$post}}{'message'}.' '.
+ $imsitems{$alldiscussion{$post}}{'attach'}.''."\n";
+ close($postingfile);
+ } else {
+ $discussion .= $lt{'aerr'}.' '.$alldiscussion{$post}.' ';
+ }
+ $copyresult.=&replicate_attachments($imsitems{$alldiscussion{$post}}{'allattachments'},$tempexport);
+ } else {
+ $discussion.=' | '. $discussionitems[$alldiscussion{$post}].
+ ' | ';
+ }
}
}
- if ($outputtarget ne 'tex') {
+ unless ($outputtarget eq 'tex' || $outputtarget eq 'export') {
my $colspan=$maxdepth+1;
$discussion .= <
-
-
+
+
-
END
- }
+ $discussion .= &action_links_bar($colspan,$ressymb,$visible,
+ $newpostsflag,$group,
+ $prevread,$markondisp);
+ $discussion .= "
+ |
+
\n";
+ }
+ if ($outputtarget eq 'export') {
+ if ($manifestok) {
+ while ($currdepth > 0) {
+ print $manifestfile " \n";
+ $currdepth --;
+ }
+ print $manifestfile qq|
+
+
+
+ $imsresources
+
+
+ |;
+ close($manifestfile);
+ if ((defined($imsextras)) && ($$imsextras{'caller'} eq 'imsexport')) {
+ $discussion = $copyresult;
+ } else {
+
+#Create zip file in prtspool
+
+ my $imszipfile = '/prtspool/'.
+ $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
+ time.'_'.rand(1000000000).'.zip';
+ my $cwd = &getcwd();
+ my $imszip = '/home/httpd/'.$imszipfile;
+ chdir $tempexport;
+ open(OUTPUT, "zip -r $imszip * 2> /dev/null |");
+ close(OUTPUT);
+ chdir $cwd;
+ $discussion .= &mt('Download the zip file from [_1]Discussion Posting Archive','').' ';
+ if ($copyresult) {
+ $discussion .= &mt('The following errors occurred during export').' - '.$copyresult;
+ }
+ }
+ } else {
+ $discussion .= ' '.&mt('Unfortunately you will not be able to retrieve an archive of the discussion posts at this time, because there was a problem creating a manifest file.').' ';
+ }
+ return $discussion;
+ }
}
if ($discussiononly) {
my $now = time;
my $attachnum = 0;
- my $newattachmsg = '';
- my @currnewattach = ();
- my @currdelold = ();
+ my $currnewattach = [];
+ my $currdelold = [];
my $comment = '';
my $subject = '';
- if ($ENV{'form.origpage'}) {
+ if ($env{'form.origpage'}) {
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['addnewattach','deloldattach','delnewattach','timestamp','idx','subject','comment']);
- $subject = &HTML::Entities::encode($ENV{'form.subject'},'<>&"');
- $comment = &HTML::Entities::encode($ENV{'form.comment'},'<>&"');
+ $subject = &unescape($env{'form.subject'});
+ $comment = &unescape($env{'form.comment'});
my @keepold = ();
- &process_attachments(\@currnewattach,\@currdelold,\@keepold);
- if (@currnewattach > 0) {
- $attachnum += @currnewattach;
+ &process_attachments($currnewattach,$currdelold,\@keepold);
+ if (@{$currnewattach} > 0) {
+ $attachnum += @{$currnewattach};
+ }
+ }
+ if (&discussion_open($status)) {
+ if (($group ne '') && ($mode eq 'board')) {
+ if (&check_group_priv($group,'pgd') eq 'ok') {
+ $discussion .=
+ &postingform_display($mode,$ressymb,$now,$subject,
+ $comment,$outputtarget,$attachnum,
+ $currnewattach,$currdelold,
+ $group,$crstype);
+ }
+ } else {
+ $discussion.=
+ &postingform_display($mode,$ressymb,$now,$subject,
+ $comment,$outputtarget,$attachnum,
+ $currnewattach,$currdelold,'',$crstype);
+ }
+ }
+ } else {
+ $discussion.='';
+ if (&discussion_open($status) &&
+ &Apache::lonnet::allowed('pch',
+ $env{'request.course.id'}.
+ ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) {
+ if ($outputtarget ne 'tex') {
+ $discussion.= &send_feedback_link($ressymb,$target);
}
+ }
+ if ($outputtarget ne 'tex') {
+ $discussion.= &send_message_link($ressymb);
+ }
+ $discussion.=' ';
+ }
+ return $discussion;
+}
+
+sub send_feedback_link {
+ my ($ressymb,$target) = @_;
+ my $output = ''.
+ ' '.
+ '';
+ return $output;
+}
+
+sub send_message_link {
+ my ($ressymb) = @_;
+ my $output = ''.
+ ' ';
+ return $output;
+}
+
+sub action_links_bar {
+ my ($colspan,$ressymb,$visible,$newpostsflag,$group,$prevread,$markondisp) = @_;
+ my $discussion = ' | '.
+ ' | ';
+ return $discussion;
+}
+
+sub postingform_display {
+ my ($mode,$ressymb,$now,$subject,$comment,$outputtarget,$attachnum,
+ $currnewattach,$currdelold,$group,$crstype) = @_;
+ my $newattachmsg;
+ my %lt = &Apache::lonlocal::texthash(
+ 'note' => 'Note: in anonymous discussion, your name is visible only to course faculty',
+ 'title' => 'Title',
+ 'podi' => 'Post Discussion',
+ 'poan' => 'Post Anonymous Discussion',
+ 'newa' => 'New attachments',
+ );
+ if ($crstype eq 'Community') {
+ $lt{'note'} = &mt('Note: in anonymous discussion, your name is visible only to community facilitators');
+ }
+ my $postingform = (<
+
-Note: in anonymous discussion, your name is visible only
-to course faculty
-Title:
-
+$lt{'note'}
+$lt{'title'}:
+
ENDDISCUSS
- if ($ENV{'form.origpage'}) {
- $discussion.=''."\n";
- foreach (@currnewattach) {
- $discussion.=''."\n";
+ if ($env{'form.origpage'}) {
+ $postingform .= ''."\n";
+ foreach my $att (@{$currnewattach}) {
+ $postingform .= ''."\n";
+ }
+ }
+ if (exists($env{'form.ref'})) {
+ $postingform .= '';
+ }
+ if ($group ne '') {
+ $postingform .='';
+ }
+ my $blockblog = &Apache::loncommon::blocking_status('blogs');
+ if (!$blockblog) {
+ $postingform .= &add_blog_checkbox($crstype);
+ }
+ $postingform .= "\n";
+ if ($outputtarget ne 'tex') {
+ $postingform .= &generate_attachments_button('',$attachnum,$ressymb,
+ $now,$currnewattach,
+ $currdelold,'',$mode,
+ $blockblog);
+ if ((ref($currnewattach) eq 'ARRAY') && (@{$currnewattach} > 0)) {
+ $newattachmsg = ' '.$lt{'newa'}.' ';
+ if (@{$currnewattach} > 1) {
+ $newattachmsg .= '';
+ foreach my $item (@{$currnewattach}) {
+ $item =~ m#.*/([^/]+)$#;
+ $newattachmsg .= '- '.$1.'
'."\n";
+ }
+ $newattachmsg .= ' '."\n";
+ } else {
+ $$currnewattach[0] =~ m#.*/([^/]+)$#;
+ $newattachmsg .= ''.$1.' '."\n";
}
}
- $discussion.="\n";
- if ($outputtarget ne 'tex') {
- $discussion.=&generate_attachments_button('',$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,'',$mode);
- if (@currnewattach > 0) {
- $newattachmsg .= 'New attachments ';
- if (@currnewattach > 1) {
- $newattachmsg .= '';
- foreach my $item (@currnewattach) {
- $item =~ m#.*/([^/]+)$#;
- $newattachmsg .= '- '.$1.'
'."\n";
+ $postingform .= $newattachmsg;
+ $postingform .= &generate_preview_button();
+ }
+ return $postingform;
+}
+
+sub build_posting_display {
+ my ($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,$grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,$anonhash,$anoncnt,$group) = @_;
+ my @original=();
+ my @index=();
+ my $skip_group_check = 0;
+ my $symb=&Apache::lonenc::check_decrypt($ressymb);
+ my $escsymb=&escape($ressymb);
+ 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 $see_anonymous =
+ &Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''));
+
+ if ((@{$grouppick} == 0) || (grep(/^all$/,@{$grouppick}))) {
+ $skip_group_check = 1;
+ }
+ if ($contrib{'version'}) {
+ my $oldest = $contrib{'1:timestamp'};
+ if ($prevread eq '0') {
+ $prevread = $oldest-1;
+ }
+ my ($skiptest,$rolematch,$roleregexp,$secregexp,$statusregexp);
+ if ($sortposts) {
+ ($skiptest,$roleregexp,$secregexp,$statusregexp) =
+ &filter_regexp($rolefilter,$sectionpick,$statusfilter);
+ $rolematch = $roleregexp.':'.$secregexp.':'.$statusregexp;
+ }
+ for (my $id=1;$id<=$contrib{'version'};$id++) {
+ my $idx=$id;
+ my $posttime = $contrib{$idx.':timestamp'};
+ if ($prevread <= $posttime) {
+ $$newpostsflag = 1;
+ }
+ my $hidden=($contrib{'hidden'}=~/\.$idx\./);
+ my $studenthidden=($contrib{'studenthidden'}=~/\.$idx\./);
+ my $deleted=($contrib{'deleted'}=~/\.$idx\./);
+ my $origindex='0.';
+ my $numoldver=0;
+ if ($contrib{$idx.':replyto'}) {
+ if ( (($env{'environment.threadeddiscussion'}) && ($sortposts eq '')) || ($sortposts eq 'thread') || ($outputtarget eq 'export')) {
+# this is a follow-up message
+ $original[$idx]=$original[$contrib{$idx.':replyto'}];
+ $$depth[$idx]=$$depth[$contrib{$idx.':replyto'}]+1;
+ $origindex=$index[$contrib{$idx.':replyto'}];
+ if ($$depth[$idx]>$$maxdepth) { $$maxdepth=$$depth[$idx]; }
+ } else {
+ $original[$idx]=0;
+ $$depth[$idx]=0;
+ }
+ } else {
+# this is an original message
+ $original[$idx]=0;
+ $$depth[$idx]=0;
+ }
+ if ($$replies[$$depth[$idx]]) {
+ $$replies[$$depth[$idx]]++;
+ } else {
+ $$replies[$$depth[$idx]]=1;
+ }
+ unless ((($hidden) && (!$seeid)) || ($deleted)) {
+ $$visible++;
+ if ($contrib{$idx.':history'}) {
+ if ($contrib{$idx.':history'} =~ /:/) {
+ my @oldversions = split(/:/,$contrib{$idx.':history'});
+ $numoldver = @oldversions;
+ } else {
+ $numoldver = 1;
+ }
+ }
+ $$current = $numoldver;
+ my %messages = ();
+ my %subjects = ();
+ my %attachtxt = ();
+ my %allattachments = ();
+ my ($screenname,$plainname);
+ my $sender = &mt('Anonymous');
+# Anonymous users getting number within a discussion
+# Since idx is in static order, this should give the same sequence every time.
+ my $key=$contrib{$idx.':sendername'}.'@'.$contrib{$idx.':senderdomain'};
+ unless ($$anonhash{$key}) {
+ $anoncnt++;
+ $$anonhash{$key}=&mt('Anonymous').' '.$anoncnt;
+ }
+ my ($message,$subject,$vgrlink,$ctlink);
+ &get_post_contents(\%contrib,$idx,$seeid,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,$numoldver);
+
+
+# Set up for sorting by subject
+ unless ($outputtarget eq 'export') {
+ $message=$messages{$numoldver};
+ $message.=$attachtxt{$numoldver};
+ $subject=$subjects{$numoldver};
+ if ($message) {
+ if ($hidden) {
+ $message=''.$message.'';
+ if ($studenthidden) {
+ $message .='
Deleted by poster (student).';
+ }
+ }
+
+ if ($subject eq '') {
+ if (defined($$subjectsort{'__No subject'})) {
+ push(@{$$subjectsort{'__No subject'}}, $idx);
+ } else {
+ @{$$subjectsort{'__No subject'}} = ("$idx");
+ }
+ } else {
+ if (defined($$subjectsort{$subject})) {
+ push(@{$$subjectsort{$subject}}, $idx);
+ } else {
+ @{$$subjectsort{$subject}} = ("$idx");
+ }
+ }
+ if (!$contrib{$idx.':anonymous'} || $see_anonymous) {
+ $sender=&Apache::loncommon::aboutmewrapper(
+ $plainname,
+ $contrib{$idx.':sendername'},
+ $contrib{$idx.':senderdomain'}).' ('.
+ $contrib{$idx.':sendername'}.':'.
+ $contrib{$idx.':senderdomain'}.')';
+ if ($contrib{$idx.':anonymous'}) {
+ $sender.=' ['.$$anonhash{$key}.'] '.
+ $screenname;
+ }
+ if ($see_anonymous) {
+ $sender.=&Apache::loncommon::student_image_tag($contrib{$idx.':senderdomain'},$contrib{$idx.':sendername'});
+ }
+# Set up for sorting by domain, then username
+ unless (defined($$usernamesort{$contrib{$idx.':senderdomain'}})) {
+ %{$$usernamesort{$contrib{$idx.':senderdomain'}}} = ();
+ }
+ if (defined($$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}})) {
+ push(@{$$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}}, $idx);
+ } else {
+ @{$$usernamesort{$contrib{$idx.':senderdomain'}}{$contrib{$idx.':sendername'}}} = ("$idx");
+ }
+# Set up for sorting by last name, then first name
+ my %names = &Apache::lonnet::get('environment',
+ ['firstname','lastname'],$contrib{$idx.':senderdomain'},
+ ,$contrib{$idx.':sendername'});
+ my $lastname = $names{'lastname'};
+ my $firstname = $names{'firstname'};
+ if ($lastname eq '') {
+ $lastname = '_';
+ }
+ if ($firstname eq '') {
+ $firstname = '_';
+ }
+ unless (defined($$namesort{$lastname})) {
+ %{$$namesort{$lastname}} = ();
+ }
+ if (defined($$namesort{$lastname}{$firstname})) {
+ push(@{$$namesort{$lastname}{$firstname}}, $idx);
+ } else {
+ @{$$namesort{$lastname}{$firstname}} = ("$idx");
+ }
+ if (&editing_allowed($escsymb.':::'.$idx,$group)) {
+ if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) {
+ $sender.=' '.&mt('Edit').'';
+
+ unless ($seeid) {
+ my $grpargs = &group_args($group);
+ $sender.=" ';
+ }
+ }
+ }
+ if ($seeid) {
+ if ($hidden) {
+ unless ($studenthidden) {
+ $sender.=' '.&mt('Make Visible').'';
+ }
+ } else {
+ $sender.=' '.&mt('Hide').'';
+ }
+ my $grpargs = &group_args($group);
+ $sender.=
+ " ";
+ $sender .= &mt('Delete').'';
+ }
+ } else {
+ if ($screenname) {
+ $sender=''.$screenname.'';
+ } else {
+ $sender=''.$$anonhash{$key}.'';
+ }
+# Set up for sorting by domain, then username for anonymous
+ unless (defined($$usernamesort{'__anon'})) {
+ %{$$usernamesort{'__anon'}} = ();
+ }
+ if (defined($$usernamesort{'__anon'}{'__anon'})) {
+ push(@{$$usernamesort{'__anon'}{'__anon'}}, $idx);
+ } else {
+ @{$$usernamesort{'__anon'}{'__anon'}} = ("$idx");
+ }
+# Set up for sorting by last name, then first name for anonymous
+ unless (defined($$namesort{'__anon'})) {
+ %{$$namesort{'__anon'}} = ();
+ }
+ if (defined($$namesort{'__anon'}{'__anon'})) {
+ push(@{$$namesort{'__anon'}{'__anon'}}, $idx);
+ } else {
+ @{$$namesort{'__anon'}{'__anon'}} = ("$idx");
+ }
+ }
+ if (&discussion_open($status)) {
+ if (($group ne '') &&
+ (&check_group_priv($group,'pgd') eq 'ok')) {
+ $sender.=' '.&mt('Reply').'';
+ } elsif (&Apache::lonnet::allowed('pch',
+ $env{'request.course.id'}.
+ ($env{'request.course.sec'}?'/'.
+ $env{'request.course.sec'}:''))) {
+ $sender.=' '.&mt('Reply').'';
+ }
+ }
+ if ($viewgrades) {
+ $vgrlink=&Apache::loncommon::submlink('Submissions',
+ $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$ressymb);
+ }
+ if ($$dischash{$readkey}=~/\.$idx\./) {
+ $ctlink = '';
+ } else {
+ $ctlink = '';
+ }
+ }
+#figure out at what position this needs to print
+ }
+ if ($outputtarget eq 'export' || $message) {
+ my $thisindex=$idx;
+ if ( (($env{'environment.threadeddiscussion'}) && ($sortposts eq '')) || ($sortposts eq 'thread') || ($outputtarget eq 'export')) {
+ $thisindex=$origindex.substr('00'.$$replies[$$depth[$idx]],-2,2);
+ }
+ $$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'}.':'.
+ $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;
}
- $newattachmsg .= ' '."\n";
} else {
- $currnewattach[0] =~ m#.*/([^/]+)$#;
- $newattachmsg .= ''.$1.' '."\n";
+ 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] .= '
+
+ '.&mt('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]).' ';
+ }
+ }
+ }
+ }
}
}
- $discussion.=$newattachmsg;
- $discussion.=&generate_preview_button();
}
+ }
+}
+
+sub filter_regexp {
+ my ($rolefilter,$sectionpick,$statusfilter) = @_;
+ my ($roleregexp,$secregexp,$statusregexp);
+ my $skiptest = 1;
+ if (@{$rolefilter} > 0) {
+ my @okrolefilter = ();
+ foreach my $role (@{$rolefilter}) {
+ unless ($role eq '') {
+ push(@okrolefilter, $role);
+ }
+ }
+ if (@okrolefilter > 0) {
+ if (grep/^all$/,@okrolefilter) {
+ $roleregexp='[^:]+';
+ } else {
+ if (@okrolefilter == 1) {
+ $roleregexp=$okrolefilter[0];
+ } else {
+ $roleregexp='('.join('|',@okrolefilter).')';
+ }
+ $skiptest = 0;
+ }
+ }
+ }
+ if (@{$sectionpick} > 0) {
+ my @oksectionpick = ();
+ foreach my $sec (@{$sectionpick}) {
+ unless ($sec eq '') {
+ push(@oksectionpick, $sec);
+ }
+ }
+ if ((@oksectionpick > 0) && (!grep/^all$/,@oksectionpick)) {
+ if (@oksectionpick == 1) {
+ $secregexp = $oksectionpick[0];
+ } else {
+ $secregexp .= '('.join('|',@oksectionpick).')';
+ }
+ $skiptest = 0;
+ } else {
+ $secregexp .= '[^:]*';
+ }
+ }
+
+ if (defined($statusfilter) && $statusfilter ne '') {
+ if ($statusfilter eq 'all') {
+ $statusregexp = '[^:]+';
+ } else {
+ $statusregexp = $statusfilter;
+ $skiptest = 0;
+ }
+ }
+ 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'}.':'.
+ $$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 (&discussion_open($status) &&
- &Apache::lonnet::allowed('pch',
- $ENV{'request.course.id'}.
- ($ENV{'request.course.sec'}?'/'.$ENV{'request.course.sec'}:''))) {
- if ($outputtarget ne 'tex') {
- $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;
+ }
+ 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 $discussion;
+ return $response;
}
sub mail_screen {
- my ($r,$feedurl,$options) = @_;
- if (exists($ENV{'form.origpage'})) {
- &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['subject','comment','currnewattach','addnewattach','deloldattach','delnewattach','timestamp','idx','anondiscuss','discuss']);
- }
- my $bodytag=&Apache::loncommon::bodytag('Resource Feedback and Discussion',
- '','onLoad="window.focus();setposttype();"');
- my $title=&Apache::lonnet::gettitle($feedurl);
- if (!$title) { $title = $feedurl; }
+ my ($r,$feedurl,$options,$caller_symb,$attachmaxtext) = @_;
+ 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(
+ 'myqu' => 'My question/comment/feedback:',
+ 'title' => 'Title',
+ 'reta' => 'Retained attachments',
+ 'atta' => 'Attachment',
+ );
+ my $restitle = &get_resource_title($caller_symb,$feedurl);
my $quote='';
my $subject = '';
my $comment = '';
@@ -930,26 +1506,31 @@ sub mail_screen {
my $attachnum = 0;
my $anonchk = (< 0) {
- if ($contrib{$idx.':message'} =~ /^/g;
- $quote=''.&Apache::lontexconvert::msgtexconverted($message).' ';
if ($idx > 0) {
- if ($contrib{$idx.':subject'} =~ /^&"');
} else {
$attachmenturls = $contrib{$idx.':attachmenturl'};
- if ($contrib{$idx.':message'} =~ /^/) {
- my %versions = ();
- &get_post_versions(\%versions,$contrib{$idx.':message'},$numoldver);
- $comment = $versions{$numoldver};
- } else {
- $comment = &HTML::Entities::encode($contrib{$idx.':message'},'<>&"');
- }
- if ($contrib{$idx.':subject'} =~ //) {
- my %versions = ();
- &get_post_versions(\%versions,$contrib{$idx.':subject'},$numoldver);
- $subject = $versions{$numoldver};
- } else {
- $subject = &HTML::Entities::encode($contrib{$idx.':subject'},'<>&"');
+ 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 = 0;
+ unless (exists($env{'form.origpage'})) {
+ my $anonflag = 'nonanon';
if ($contrib{$idx.':anonymous'}) {
- $anonflag = 1;
+ $anonflag = 'anon';
}
$anonscript = (<';
+ if ($env{'form.previous'}) {
+ $prevtag = '';
}
}
- if ($ENV{'form.origpage'}) {
- $subject = $ENV{'form.subject'};
- $comment = $ENV{'form.comment'};
+ 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 $htmlheader=&Apache::lonhtmlcommon::htmlareaheaders();
+ my $latexHelp=&Apache::loncommon::helpLatexCheatsheet(undef,undef,1);
my $send=&mt('Send');
- $r->print(<
-
-The LearningOnline Network with CAPA
-
-$htmlheader
+ my $alert = &mt('Please select a feedback type.');
+ my $js= <
//
-
-$bodytag
-$title
+END
+
+ # Breadcrumbs
+ my $brcrum = [{'href' => '',
+ 'text' => 'Resource Feedback and Discussion'}];
+
+ my %onload = ('onload' => 'window.focus();setposttype();');
+ my $start_page=
+ &Apache::loncommon::start_page('Resource Feedback and Discussion',$js,
+ {'add_entries' => \%onload,
+ 'bread_crumbs' => $brcrum,});
+
+ if ($quote ne '') {
+ &newline_to_br(\$quote);
+ $quote=''.&Apache::lontexconvert::msgtexconverted($quote).' ';
+ }
+
+ $r->print(<$restitle
END
- if ($ENV{'form.editdisc'} || $ENV{'form.replydisc'}) {
+ if ($env{'form.editdisc'} || $env{'form.replydisc'}) {
my $now = time;
my $ressymb = $symb;
+ &Apache::lonenc::check_encrypt(\$ressymb);
my $postidx = '';
- if ($ENV{'form.editdisc'}) {
+ if ($env{'form.editdisc'}) {
$postidx = $idx;
}
if (@currnewattach > 0) {
$attachnum += @currnewattach;
}
- $r->print(&generate_attachments_button($postidx,$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,$numoldver));
+ my $blockblog = &Apache::loncommon::blocking_status('blogs');
+ $r->print(&generate_attachments_button($postidx,$attachnum,$ressymb,$now,\@currnewattach,\@currdelold,$numoldver,'',$blockblog));
if ($attachnum > 0) {
if (@currnewattach > 0) {
- $newattachmsg .= 'New attachments ';
+ $newattachmsg .= ' '.&mt('New attachments').' ';
if (@currnewattach > 1) {
$newattachmsg .= '';
foreach my $item (@currnewattach) {
@@ -1210,7 +1777,7 @@ END
}
}
if ($attachmsg) {
- $r->print("Retained attachments:$attachmsg \n");
+ $r->print(" $lt{'reta'}:$attachmsg \n");
}
if ($newattachmsg) {
$r->print("$newattachmsg ");
@@ -1219,37 +1786,33 @@ END
}
$r->print(&generate_preview_button().
&Apache::lonhtmlcommon::htmlareaselectactive('comment').
- ' |
|