';
+ 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);
+ }
}
- my $idx;
- for ($idx=1;$idx<=$contrib{'version'};$idx++) {
+ if ($outputtarget ne 'tex') {
+ $discussion.= &send_message_link($ressymb);
+ }
+ $discussion.='
';
+ }
+ return $discussion;
+}
+
+sub send_feedback_link {
+ my ($ressymb,$target) = @_;
+ my $output = '
+
+
+
+
+$lt{'note'}
+$lt{'title'}:
+
+ENDDISCUSS
+ 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";
+ }
+ }
+ $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)) {
- my $message=$contrib{$idx.':message'};
- $message=~s/\n/\
/g;
- $message=&Apache::lontexconvert::msgtexconverted($message);
- if ($contrib{$idx.':attachmenturl'}) {
- my ($fname,$ft)
- =($contrib{$idx.':attachmenturl'}=~/\/(\w+)\.(\w+)$/);
- $message.='Attachment: '.$fname.'.'.$ft.'';
+ $$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;
}
- if ($message) {
- if ($hidden) {
- $message=''.$message.'';
- }
- my $screenname=&Apache::loncommon::screenname(
- $contrib{$idx.':sendername'},
- $contrib{$idx.':senderdomain'});
- my $plainname=&Apache::loncommon::nickname(
- $contrib{$idx.':sendername'},
- $contrib{$idx.':senderdomain'});
-
- my $sender='Anonymous';
- if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {
- $sender=&Apache::loncommon::aboutmewrapper(
+ 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'}.' at '.
+ $contrib{$idx.':sendername'}.':'.
$contrib{$idx.':senderdomain'}.')';
- if ($contrib{$idx.':anonymous'}) {
- $sender.=' [anonymous] '.
- $screenname;
- }
- if ($seeid) {
- if ($hidden) {
- $sender.=' Make Visible';
+ 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.=' Hide';
- }
- $sender.=' Delete';
- }
- } else {
- if ($screenname) {
- $sender=''.$screenname.'';
- }
- }
- my $vgrlink;
- if ($viewgrades) {
- $vgrlink=&Apache::loncommon::submlink('Submissions',
- $contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'},$symb);
+ $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);
}
- $discussion.='
'.$sender.' '.$vgrlink.' ('.
- localtime($contrib{$idx.':timestamp'}).
- '):
'.$message.
- '
';
- }
- }
- }
- unless ($discussiononly) {
- $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'}.':'.
+ $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] .= '
+
+ '.&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]).' ';
+ }
+ }
+ }
+ }
+ }
+ }
}
}
- if ($discussiononly) {
- $discussion.=(<
-
-
-
-
-
-Note: in anonymous discussion, your name is visible only to
-course faculty
-
-
-Attachment (128 KB max size):
-
-
-ENDDISCUSS
- $discussion.=&generate_preview_button();
- }
- return $discussion;
}
-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 $latexHelp = Apache::loncommon::helpLatexCheatsheet();
- $r->print(<
-
-The LearningOnline Network with CAPA
-
-
-
-$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
-ENDDOCUMENT
-$r->print(&generate_preview_button().'