version 1.330, 2012/01/09 19:56:28
|
version 1.339, 2012/03/13 05:37:49
|
Line 82 sub discussion_visible {
|
Line 82 sub discussion_visible {
|
return 1; |
return 1; |
} |
} |
|
|
|
sub discussion_vote_available { |
|
my ($status,$symb)=@_; |
|
my $canvote=&Apache::lonnet::EXT('resource.0.discussvote',$symb); |
|
if ((lc($canvote) eq 'yes') || |
|
((lc($canvote) eq 'notended') && (&discussion_open($status,$symb)))) { |
|
return 1; |
|
} |
|
} |
|
|
|
sub get_realsymb { |
|
my ($symb) = @_; |
|
my $realsymb = $symb; |
|
if ($symb=~/^bulletin___/) { |
|
my $filename=(&Apache::lonnet::decode_symb($symb))[2]; |
|
$filename=~s{^adm/wrapper/}{}; |
|
$realsymb=&Apache::lonnet::symbread($filename); |
|
} |
|
return $realsymb; |
|
} |
|
|
sub list_discussion { |
sub list_discussion { |
my ($mode,$status,$ressymb,$imsextras,$group)=@_; |
my ($mode,$status,$ressymb,$imsextras,$group)=@_; |
unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); } |
unless ($ressymb) { $ressymb=&Apache::lonnet::symbread(); } |
Line 265 sub list_discussion {
|
Line 285 sub list_discussion {
|
} else { |
} else { |
$seeid=&Apache::lonnet::allowed('rin',$crs); |
$seeid=&Apache::lonnet::allowed('rin',$crs); |
} |
} |
|
|
|
# Is voting on discussions available |
|
my $realsymb = &get_realsymb($ressymb); |
|
my $canvote = &discussion_vote_available($status,$realsymb); |
|
|
my @discussionitems=(); |
my @discussionitems=(); |
my %shown = (); |
my %shown = (); |
my @posteridentity=(); |
my @posteridentity=(); |
Line 286 sub list_discussion {
|
Line 311 sub list_discussion {
|
$discinfo{$visitkey} = $visit; |
$discinfo{$visitkey} = $visit; |
|
|
&Apache::lonnet::put('nohist_'.$cid.'_discuss',\%discinfo,$env{'user.domain'},$env{'user.name'}); |
&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,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,\@grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,\%anonhash,$anoncnt,$group); |
&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,$canvote,$prevread,$sortposts,$encsymb,$readkey,$showunmark,$showonlyunread,$totposters,\@rolefilter,\@sectionpick,\@grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,\%anonhash,$anoncnt,$group); |
|
|
my $discussion=''; |
my $discussion=''; |
my $manifestfile; |
my $manifestfile; |
Line 744 END
|
Line 769 END
|
$discussion.= &send_feedback_link($ressymb); |
$discussion.= &send_feedback_link($ressymb); |
if ($env{'request.role.adv'}) { |
if ($env{'request.role.adv'}) { |
my $close = &Apache::lonnet::EXT('resource.0.discussend',$ressymb); |
my $close = &Apache::lonnet::EXT('resource.0.discussend',$ressymb); |
|
my $canvote = &Apache::lonnet::EXT('resource.0.discussvote',$ressymb); |
if (defined($close) && $close ne '' && $close < time) { |
if (defined($close) && $close ne '' && $close < time) { |
$discussion .= ' '.&mt('(Closed for [_1] roles)', |
if ($canvote eq 'notended') { |
&Apache::lonnet::plaintext('st',$crstype)); |
$discussion .= ' '.&mt('(Posting and voting closed for [_1] roles)', |
|
&Apache::lonnet::plaintext('st',$crstype)); |
|
} else { |
|
$discussion .= ' '.&mt('(Closed for [_1] roles)', |
|
&Apache::lonnet::plaintext('st',$crstype)); |
|
} |
} |
} |
} |
} |
} else { |
} else { |
Line 937 ENDDISCUSS
|
Line 968 ENDDISCUSS
|
} |
} |
|
|
sub build_posting_display { |
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,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,$anonhash,$anoncnt,$group) = @_; |
my ($usernamesort,$subjectsort,$namesort,$notshown,$newitem,$dischash,$shown,$alldiscussion,$imsitems,$imsfiles,$roleinfo,$discussionitems,$replies,$depth,$posters,$maxdepth,$visible,$newpostsflag,$current,$status,$viewgrades,$seeid,$canvote,$prevread,$sortposts,$ressymb,$readkey,$showunmark,$showonlyunread,$totposters,$rolefilter,$sectionpick,$grouppick,$classgroups,$statusfilter,$toggkey,$outputtarget,$anonhash,$anoncnt,$group) = @_; |
my @original=(); |
my @original=(); |
my @index=(); |
my @index=(); |
my $skip_group_check = 0; |
my $skip_group_check = 0; |
Line 947 sub build_posting_display {
|
Line 978 sub build_posting_display {
|
my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'}, |
my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.num'}); |
$env{'course.'.$env{'request.course.id'}.'.num'}); |
|
my (%likes,%userlikes,%userunlikes,@theselikes,$oneplus,$twoplus,$oneminus,$twominus); |
|
my $thisuser=$env{'user.name'}.':'.$env{'user.domain'}; |
|
if ($seeid || $canvote) { |
# And these are the likes/unlikes |
# And these are the likes/unlikes |
my %likes=&Apache::lonnet::dump('disclikes', |
%likes=&Apache::lonnet::dump('disclikes', |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.num'}, |
$env{'course.'.$env{'request.course.id'}.'.num'}, |
'^'.$symb.':'); |
'^'.$symb.':'); |
my $thisuser=$env{'user.name'}.':'.$env{'user.domain'}; |
|
# Array with likes to figure out averages, etc. |
# Array with likes to figure out averages, etc. |
my @theselikes=(); |
@theselikes=(); |
|
# Hashes containing likes and unlikes for this user. |
|
%userlikes=(); |
|
%userunlikes=(); |
|
} |
# Is the user allowed to see the real name behind anonymous postings? |
# Is the user allowed to see the real name behind anonymous postings? |
my $see_anonymous = |
my $see_anonymous = |
&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); |
&Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); |
Line 988 sub build_posting_display {
|
Line 1025 sub build_posting_display {
|
&filter_regexp($rolefilter,$sectionpick,$statusfilter); |
&filter_regexp($rolefilter,$sectionpick,$statusfilter); |
$rolematch = $roleregexp.':'.$secregexp.':'.$statusregexp; |
$rolematch = $roleregexp.':'.$secregexp.':'.$statusregexp; |
} |
} |
|
if ($seeid || $canvote) { |
# We need to go through this twice, first to get the likes/dislikes, then to actually build the display |
# We need to go through this twice, first to get the likes/dislikes, then to actually build the display |
for (my $id=1;$id<=$contrib{'version'};$id++) { |
for (my $id=1;$id<=$contrib{'version'};$id++) { |
my $idx=$id; |
my $idx=$id; |
next if ($contrib{$idx.':deleted'}); |
next if ($contrib{$idx.':deleted'}); |
next if ($contrib{$idx.':hidden'}); |
next if ($contrib{$idx.':hidden'}); |
unless ((($hiddens{$idx}) && (!$seeid)) || ($deletions{$idx}) || (!$contrib{$idx.':message'})) { |
unless ((($hiddens{$idx}) && (!$seeid)) || ($deletions{$idx}) || (!$contrib{$idx.':message'})) { |
push(@theselikes,$likes{$symb.':'.$idx.':likes'}); |
if ($likes{$symb.':'.$idx.':likes'} ne '') { |
|
push(@theselikes,$likes{$symb.':'.$idx.':likes'}); |
|
if (ref($likes{$symb.':'.$idx.':likers'}) eq 'HASH') { |
|
if (exists($likes{$symb.':'.$idx.':likers'}{$thisuser})) { |
|
$userlikes{$idx} = 1; |
|
} |
|
} |
|
if (ref($likes{$symb.':'.$idx.':unlikers'}) eq 'HASH') { |
|
if (exists($likes{$symb.':'.$idx.':unlikers'}{$thisuser})) { |
|
$userunlikes{$idx} = 1; |
|
} |
|
} |
|
} |
|
} |
} |
} |
} |
# Figure out average likes and standard deviation if there are enough |
# Figure out average likes and standard deviation if there are enough discussions to warrant that |
# discussions to warrant that |
my $ave=0; |
my $ave=0; |
my $stddev=10000; |
my $stddev=10000; |
if ($#theselikes>1) { |
if ($#theselikes>1) { |
my $sum=0; |
my $sum=0; |
my $num=$#theselikes+1; |
my $num=$#theselikes+1; |
foreach my $thislike (@theselikes) { |
foreach my $thislike (@theselikes) { |
$sum+=$thislike; |
$sum+=$thislike; |
} |
} |
$ave=$sum/$num; |
$ave=$sum/$num; |
my $sumsq=0; |
my $sumsq=0; |
foreach my $thislike (@theselikes) { |
foreach my $thislike (@theselikes) { |
$sumsq+=($thislike-$ave)*($thislike-$ave); |
$sumsq+=($thislike-$ave)*($thislike-$ave); |
|
} |
|
$stddev=sqrt($sumsq/$num); |
} |
} |
$stddev=sqrt($sumsq/$num); |
|
} |
|
# Now we know the average likes $ave and the standard deviation $stddev |
# Now we know the average likes $ave and the standard deviation $stddev |
# Get the boundaries for markup |
# Get the boundaries for markup |
my $oneplus=$ave+$stddev; |
$oneplus=$ave+$stddev; |
my $twoplus=$ave+2.*$stddev; |
$twoplus=$ave+2.*$stddev; |
my $oneminus=$ave-$stddev; |
$oneminus=$ave-$stddev; |
my $twominus=$ave-2.*$stddev; |
$twominus=$ave-2.*$stddev; |
# &Apache::lonnet::logthis(join(',',@theselikes)." Ave $ave StdDev $stddev $twominus $oneminus $oneplus $twoplus"); |
} |
# |
# |
# This is now the real loop. Go through all entries, pick up what we need |
# This is now the real loop. Go through all entries, pick up what we need |
# |
# |
for (my $id=1;$id<=$contrib{'version'};$id++) { |
for (my $id=1;$id<=$contrib{'version'};$id++) { |
my $idx=$id; |
my $idx=$id; |
next if ($contrib{$idx.':deleted'}); |
next if ($contrib{$idx.':deleted'}); |
Line 1072 sub build_posting_display {
|
Line 1123 sub build_posting_display {
|
my %subjects = (); |
my %subjects = (); |
my %attachtxt = (); |
my %attachtxt = (); |
my %allattachments = (); |
my %allattachments = (); |
my ($screenname,$plainname); |
my ($screenname,$plainname,$showaboutme); |
my $sender = &mt('Anonymous'); |
my $sender = &mt('Anonymous'); |
# Anonymous users getting number within a discussion |
# Anonymous users getting number within a discussion |
# Since idx is in static order, this should give the same sequence every time. |
# Since idx is in static order, this should give the same sequence every time. |
Line 1082 sub build_posting_display {
|
Line 1133 sub build_posting_display {
|
$$anonhash{$key}=&mt('Anonymous').' '.$anoncnt; |
$$anonhash{$key}=&mt('Anonymous').' '.$anoncnt; |
} |
} |
my ($message,$subject,$vgrlink,$ctlink); |
my ($message,$subject,$vgrlink,$ctlink); |
&get_post_contents(\%contrib,$idx,$seeid,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,$numoldver); |
&get_post_contents(\%contrib,$idx,$seeid,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,\$showaboutme,$numoldver); |
|
|
|
|
# Set up for sorting by subject |
# Set up for sorting by subject |
Line 1112 sub build_posting_display {
|
Line 1163 sub build_posting_display {
|
} |
} |
} |
} |
if (!$contrib{$idx.':anonymous'} || $see_anonymous) { |
if (!$contrib{$idx.':anonymous'} || $see_anonymous) { |
$sender=&Apache::loncommon::aboutmewrapper( |
if ($showaboutme) { |
$plainname, |
$sender = &Apache::loncommon::aboutmewrapper( |
$contrib{$idx.':sendername'}, |
$plainname, |
$contrib{$idx.':senderdomain'}).' ('. |
$contrib{$idx.':sendername'}, |
$contrib{$idx.':sendername'}.':'. |
$contrib{$idx.':senderdomain'}); |
$contrib{$idx.':senderdomain'}.')'; |
} else { |
|
$sender = $plainname; |
|
} |
|
if ($see_anonymous) { |
|
$sender .= ' ('.$contrib{$idx.':sendername'}.':'. |
|
$contrib{$idx.':senderdomain'}.')'; |
|
} |
$sender = '<b>'.$sender.'</b>'; |
$sender = '<b>'.$sender.'</b>'; |
if ($contrib{$idx.':anonymous'}) { |
if ($contrib{$idx.':anonymous'}) { |
$sender.=' <font color="red"><b>['.$$anonhash{$key}.']</b></font> '. |
$sender.=' <font color="red"><b>['.$$anonhash{$key}.']</b></font> '. |
Line 1156 sub build_posting_display {
|
Line 1213 sub build_posting_display {
|
@{$$namesort{$lastname}{$firstname}} = ("$idx"); |
@{$$namesort{$lastname}{$firstname}} = ("$idx"); |
} |
} |
if ($outputtarget ne 'tex') { |
if ($outputtarget ne 'tex') { |
unless ($likes{$symb.':'.$idx.':likers'}=~/\,\Q$thisuser\E\,/) { |
# Add karma stars |
$sender.=' '.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsup.png" alt="'.&mt('Like').'" />','like',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Like")); |
my $karma=&userkarma($contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'}); |
} |
for (my $i=1;$i<=$karma;$i++) { |
unless ($likes{$symb.':'.$idx.':unlikers'}=~/\,\Q$thisuser\E\,/) { |
$sender.='<img border="0" src="/res/adm/pages/star.gif" alt="'.&mt('Contributor Kudos').'" />'; |
$sender.=' '.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsdown.png" alt="'.&mt('Unlike').'" />',,'unlike',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Unlike")); |
|
} |
|
my $thislikes=$likes{$symb.':'.$idx.':likes'}; |
|
if ($thislikes>0) { |
|
$sender.=' ('.&mt("[_1] likes",$thislikes).')'; |
|
} elsif ($thislikes<0) { |
|
$sender.=' ('.&mt("[_1] unlikes",abs($thislikes)).')'; |
|
} |
} |
|
# Can people edit this? |
if (&editing_allowed($escsymb.':::'.$idx,$group)) { |
if (&editing_allowed($escsymb.':::'.$idx,$group)) { |
if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) { |
if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) { |
$sender.=' '. |
$sender.=' '. |
Line 1350 sub build_posting_display {
|
Line 1401 sub build_posting_display {
|
if ($$dischash{$toggkey}) { |
if ($$dischash{$toggkey}) { |
$$discussionitems[$idx].=' '.$ctlink; |
$$discussionitems[$idx].=' '.$ctlink; |
} |
} |
# Figure out size based on likes |
|
my $thislikes=$likes{$symb.':'.$idx.':likes'}; |
my $thislikes=$likes{$symb.':'.$idx.':likes'}; |
my $likesize="100"; |
my $likesize="100"; |
if ($thislikes>$twoplus) { |
if ($seeid || $canvote) { |
$likesize="200"; |
# Figure out size based on likes |
} elsif ($thislikes>$oneplus) { |
my $thislikes=$likes{$symb.':'.$idx.':likes'}; |
$likesize="150"; |
if ($thislikes>$twoplus) { |
} |
$likesize="200"; |
if ($thislikes<$twominus) { |
} elsif ($thislikes>$oneplus) { |
$likesize="50"; |
$likesize="150"; |
} elsif ($thislikes<$oneminus) { |
} |
$likesize="75"; |
if ($thislikes<$twominus) { |
|
$likesize="50"; |
|
} elsif ($thislikes<$oneminus) { |
|
$likesize="75"; |
|
} |
} |
} |
|
# Actually glue in the message itself |
$$discussionitems[$idx].= '<br /><blockquote>'. |
$$discussionitems[$idx].= '<br /><blockquote>'. |
"<div style='font-size:$likesize%'>". |
"<div style='font-size:$likesize%'>". |
$message. |
$message. |
'</div></blockquote>'; |
'</div></blockquote>'; |
|
if ($canvote) { |
|
# Put in the like and unlike buttons |
|
if ($userlikes{$idx}) { |
|
$$discussionitems[$idx].='<img border="0" src="/res/adm/pages/thumbsup_gray.png" alt="'.&mt('You like this posting').'" />'; |
|
} else { |
|
$$discussionitems[$idx].=' '.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsup.png" alt="'.&mt('Like').'" />','like',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Like this posting")); |
|
} |
|
if ($userunlikes{$idx}) { |
|
$$discussionitems[$idx].='<img border="0" src="/res/adm/pages/thumbsdown_gray.png" alt="'.&mt('You unlike this posting').'" />'; |
|
} else { |
|
$$discussionitems[$idx].=' '.&discussion_link($symb,'<img border="0" src="/res/adm/pages/thumbsdown.png" alt="'.&mt('Unlike').'" />','unlike',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Unlike this posting")); |
|
} |
|
} |
|
if ($seeid || $canvote) { |
|
my $thislikes=$likes{$symb.':'.$idx.':likes'}; |
|
if ($thislikes>0) { |
|
$$discussionitems[$idx].=' ('.&mt("[_1] likes",$thislikes).')'; |
|
} elsif ($thislikes<0) { |
|
$$discussionitems[$idx].=' ('.&mt("[_1] unlikes",abs($thislikes)).')'; |
|
} |
|
} |
|
# If there is any history to this post, inform the reader |
if ($contrib{$idx.':history'}) { |
if ($contrib{$idx.':history'}) { |
my @postversions = (); |
my @postversions = (); |
$$discussionitems[$idx] .= &mt('This post has been edited by the author.'); |
$$discussionitems[$idx] .= ' '.&mt('This post has been edited by the author.'); |
if ($seeid) { |
if ($seeid) { |
$$discussionitems[$idx] .= ' '. |
$$discussionitems[$idx] .= ' '. |
&discussion_link($symb,&mt('Display all versions'),'allversions',$idx,$$newpostsflag,$prevread,&group_args($group)); |
&discussion_link($symb,&mt('Display all versions'),'allversions',$idx,$$newpostsflag,$prevread,&group_args($group)); |
Line 1456 sub filter_regexp {
|
Line 1533 sub filter_regexp {
|
|
|
|
|
sub get_post_contents { |
sub get_post_contents { |
my ($contrib,$idx,$seeid,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$numver) = @_; |
my ($contrib,$idx,$seeid,$type,$messages,$subjects,$allattachments,$attachtxt,$imsfiles,$screenname,$plainname,$showaboutme,$numver) = @_; |
my $discussion = ''; |
my $discussion = ''; |
my $start=$numver; |
my $start=$numver; |
my $end=$numver + 1; |
my $end=$numver + 1; |
Line 1474 sub get_post_contents {
|
Line 1551 sub get_post_contents {
|
$$contrib{$idx.':sendername'}, |
$$contrib{$idx.':sendername'}, |
$$contrib{$idx.':senderdomain'}); |
$$contrib{$idx.':senderdomain'}); |
$$screenname=$$contrib{$idx.':screenname'}; |
$$screenname=$$contrib{$idx.':screenname'}; |
|
$$showaboutme = &Apache::lonnet::usertools_access($$contrib{$idx.':sendername'}, |
my $sender=&Apache::loncommon::aboutmewrapper( |
$$contrib{$idx.':senderdomain'}, |
|
'aboutme'); |
|
my $sender = $$plainname; |
|
if ($$showaboutme) { |
|
$sender = &Apache::loncommon::aboutmewrapper( |
$$plainname, |
$$plainname, |
$$contrib{$idx.':sendername'}, |
$$contrib{$idx.':sendername'}, |
$$contrib{$idx.':senderdomain'}).' ('. |
$$contrib{$idx.':senderdomain'}); |
$$contrib{$idx.':sendername'}.':'. |
} |
$$contrib{$idx.':senderdomain'}.')'; |
if ($seeid) { |
|
$sender .= ' ('.$$contrib{$idx.':sendername'}.':'. |
|
$$contrib{$idx.':senderdomain'}.')'; |
|
} |
my $attachmenturls = $$contrib{$idx.':attachmenturl'}; |
my $attachmenturls = $$contrib{$idx.':attachmenturl'}; |
my @postversions = (); |
my @postversions = (); |
if ($type eq 'allversions' || $type eq 'export') { |
if ($type eq 'allversions' || $type eq 'export') { |
Line 2683 sub no_redirect_back {
|
Line 2767 sub no_redirect_back {
|
'add_entries' => \%onload,); |
'add_entries' => \%onload,); |
|
|
if ($feedurl !~ m{^/adm/feedback}) { |
if ($feedurl !~ m{^/adm/feedback}) { |
$body_options{'rediect'} = [2,$feedurl]; |
$body_options{'redirect'} = [2,$feedurl]; |
} |
} |
my $start_page= |
my $start_page= |
&Apache::loncommon::start_page('Feedback not sent',undef, |
&Apache::loncommon::start_page('Feedback not sent',undef, |
Line 2754 sub screen_header {
|
Line 2838 sub screen_header {
|
my ($blocked,$blocktext) = &Apache::loncommon::blocking_status('boards'); |
my ($blocked,$blocktext) = &Apache::loncommon::blocking_status('boards'); |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
my $realsymb = $symb; |
my $realsymb = &get_realsymb($symb); |
if ($symb=~/^bulletin___/) { |
|
my $filename=(&Apache::lonnet::decode_symb($symb))[2]; |
|
$filename=~s|^adm/wrapper/||; |
|
$realsymb=&Apache::lonnet::symbread($filename); |
|
} |
|
if (!$blocked && &discussion_open(undef,$realsymb) && |
if (!$blocked && &discussion_open(undef,$realsymb) && |
(&Apache::lonnet::allowed('pch', |
(&Apache::lonnet::allowed('pch', |
$env{'request.course.id'}. |
$env{'request.course.id'}. |
Line 2935 sub storefeedbackpoints {
|
Line 3014 sub storefeedbackpoints {
|
my %record=('grader_user' => $env{'user.name'}, |
my %record=('grader_user' => $env{'user.name'}, |
'grader_domain' => $env{'user.domain'}, |
'grader_domain' => $env{'user.domain'}, |
'points' => $points); |
'points' => $points); |
return &Apache::lonnet::cstore(\%record,'_feedback'); |
return &Apache::lonnet::cstore(\%record,'_feedback',$course,$udom,$uname); |
} |
} |
|
|
# Store feedback "likes" |
# Store feedback "likes" |
Line 2955 sub storefeedbacklikes {
|
Line 3034 sub storefeedbacklikes {
|
'likes_domain' => $env{'user.domain'}, |
'likes_domain' => $env{'user.domain'}, |
'likes' => $likes, |
'likes' => $likes, |
'totallikes' => $totallikes); |
'totallikes' => $totallikes); |
return &Apache::lonnet::cstore(\%newrecord,'_feedback'); |
return &Apache::lonnet::cstore(\%newrecord,'_feedback',$course,$udom,$uname); |
} |
} |
|
|
|
|
sub adddiscuss { |
sub adddiscuss { |
my ($symb,$email,$anon,$attachmenturl,$subject,$group)=@_; |
my ($symb,$email,$anon,$attachmenturl,$subject,$group)=@_; |
my $status=''; |
my $status=''; |
my $realsymb; |
my $realsymb = &get_realsymb($symb); |
if ($symb=~/^bulletin___/) { |
|
my $filename=(&Apache::lonnet::decode_symb($symb))[2]; |
|
$filename=~s|^adm/wrapper/||; |
|
$realsymb=&Apache::lonnet::symbread($filename); |
|
} |
|
my ($cnum,$cdom); |
my ($cnum,$cdom); |
if ($env{'request.course.id'}) { |
if ($env{'request.course.id'}) { |
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
Line 3065 sub adddiscuss {
|
Line 3139 sub adddiscuss {
|
$newrecord{'subnumber'}=$record{'subnumber'}+1; |
$newrecord{'subnumber'}=$record{'subnumber'}+1; |
$status.='<br />'.&mt('Registering').': '. |
$status.='<br />'.&mt('Registering').': '. |
&Apache::lonnet::cstore(\%newrecord,'_discussion'); |
&Apache::lonnet::cstore(\%newrecord,'_discussion'); |
|
&updatekarma(); |
} |
} |
} else { |
} else { |
$status.='Failed.'; |
$status.='Failed.'; |
Line 3088 sub getdiscussionrecords {
|
Line 3163 sub getdiscussionrecords {
|
|
|
sub getdiscussionstats { |
sub getdiscussionstats { |
my %record=&getdiscussionrecords(@_); |
my %record=&getdiscussionrecords(@_); |
return ($record{'subnumber'},$record{'points'},$record{'totallikes'}); |
return ($record{'subnumber'},$record{'points'},$record{'totallikes'},$record{'totalvotes'}); |
|
} |
|
|
|
# Calculate discussion karma |
|
|
|
sub calcdiscussionkarma { |
|
my ($subs,$pts,$likes,$votes)=&getdiscussionstats(@_); |
|
my $karma=0; |
|
if ($votes>0) { |
|
$karma=int(.1+5.*(1.-exp(-$subs/10.))*$likes/$votes); |
|
if ($karma<0) { $karma=0; } |
|
if ($karma>5) { $karma=5; } |
|
} |
|
return $karma; |
|
} |
|
|
|
# Update karma |
|
|
|
sub updatekarma { |
|
my ($uname,$udom,$course)=@_; |
|
unless ($uname) { $uname=$env{'user.name'}; } |
|
unless ($udom) { $udom=$env{'user.domain'}; } |
|
unless ($course) { $course=$env{'request.course.id'}; } |
|
my $karma=&calcdiscussionkarma($uname,$udom,$course); |
|
&Apache::lonnet::cstore({ 'karma' => $karma },'_discussion',$course,$udom,$uname); |
|
&Apache::lonnet::do_cache_new('karma',$uname.':'.$udom.':'.$course,$karma,3600); |
|
return $karma; |
} |
} |
|
|
|
# Retrieve karma |
|
|
|
sub userkarma { |
|
my ($uname,$udom,$course)=@_; |
|
unless ($uname) { $uname=$env{'user.name'}; } |
|
unless ($udom) { $udom=$env{'user.domain'}; } |
|
unless ($course) { $course=$env{'request.course.id'}; } |
|
my $hashkey=$uname.':'.$udom.':'.$course; |
|
my ($karma,$cached)=&Apache::lonnet::is_cached_new('karma',$hashkey); |
|
if ($cached) { |
|
return $karma; |
|
} |
|
my %userdisc=&getdiscussionrecords($uname,$udom,$course); |
|
$karma=$userdisc{'karma'}; |
|
&Apache::lonnet::do_cache_new('karma',$hashkey,$karma,3600); |
|
return $karma; |
|
} |
|
|
# Store discussion credit |
# Store discussion credit |
|
|
Line 3103 sub storediscussionpoints {
|
Line 3221 sub storediscussionpoints {
|
my %record=('grader_user' => $env{'user.name'}, |
my %record=('grader_user' => $env{'user.name'}, |
'grader_domain' => $env{'user.domain'}, |
'grader_domain' => $env{'user.domain'}, |
'points' => $points); |
'points' => $points); |
return &Apache::lonnet::cstore(\%record,'_discussion'); |
return &Apache::lonnet::cstore(\%record,'_discussion',$course,$udom,$uname); |
} |
} |
|
|
# Store discussion "likes" |
# Store discussion "likes" |
Line 3118 sub storediscussionlikes {
|
Line 3236 sub storediscussionlikes {
|
unless ($course) { $course=$env{'request.course.id'}; } |
unless ($course) { $course=$env{'request.course.id'}; } |
my %record=&getdiscussionrecords($uname,$udom,$course); |
my %record=&getdiscussionrecords($uname,$udom,$course); |
my $totallikes=$record{'totallikes'}; |
my $totallikes=$record{'totallikes'}; |
|
my $totalvotes=$record{'totalvotes'}; |
$totallikes+=$likes; |
$totallikes+=$likes; |
|
$totalvotes++; |
my %newrecord=('likes_user' => $env{'user.name'}, |
my %newrecord=('likes_user' => $env{'user.name'}, |
'likes_domain' => $env{'user.domain'}, |
'likes_domain' => $env{'user.domain'}, |
'likes' => $likes, |
'likes' => $likes, |
'totallikes' => $totallikes); |
'totallikes' => $totallikes, |
return &Apache::lonnet::cstore(\%newrecord,'_discussion'); |
'totalvotes' => $totalvotes); |
|
my $status=&Apache::lonnet::cstore(\%newrecord,'_discussion',$course,$udom,$uname); |
|
if ($status eq 'ok') { |
|
&updatekarma($uname,$udom,$course); |
|
} |
|
return $status; |
} |
} |
|
|
sub get_discussion_info { |
sub get_discussion_info { |
Line 3411 sub generate_attachments_button {
|
Line 3536 sub generate_attachments_button {
|
my ($idx,$attachnum,$ressymb,$now,$currnewattach,$deloldattach, |
my ($idx,$attachnum,$ressymb,$now,$currnewattach,$deloldattach, |
$numoldver,$mode,$blockblog) = @_; |
$numoldver,$mode,$blockblog) = @_; |
my $origpage = $ENV{'REQUEST_URI'}; |
my $origpage = $ENV{'REQUEST_URI'}; |
my $att=$attachnum.' '.&mt("attachments"); |
|
my %lt = &Apache::lonlocal::texthash( |
my %lt = &Apache::lonlocal::texthash( |
'clic' => 'Click to add/remove attachments', |
'clic' => 'Add/remove attachments', |
); |
); |
my $response = (<<END); |
my $response = (<<END); |
<br /> |
<br /> |
<form name="attachment" action="/adm/feedback?attach=$ressymb" method="post"> |
<form name="attachment" action="/adm/feedback?attach=$ressymb" method="post"> |
$lt{'clic'}: <input type="button" value="$att" |
<input type="button" value="$lt{'clic'}" |
onclick="if (typeof(document.mailform.onsubmit)=='function') {document.mailform.onsubmit();};this.form.comment.value=escape(document.mailform.comment.value);this.form.subject.value=escape(document.mailform.subject.value); |
onclick="if (typeof(document.mailform.onsubmit)=='function') {document.mailform.onsubmit();};this.form.comment.value=escape(document.mailform.comment.value);this.form.subject.value=escape(document.mailform.subject.value); |
END |
END |
if (!$blockblog) { |
if (!$blockblog) { |
Line 3736 sub handler {
|
Line 3860 sub handler {
|
my %attachmsgs = (); |
my %attachmsgs = (); |
my %allattachments = (); |
my %allattachments = (); |
my %imsfiles = (); |
my %imsfiles = (); |
my ($screenname,$plainname); |
my ($screenname,$plainname,$showaboutme); |
my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'}, |
my %contrib=&Apache::lonnet::restore($symb,$env{'request.course.id'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.num'}); |
$env{'course.'.$env{'request.course.id'}.'.num'}); |
$r->print(&get_post_contents(\%contrib,$idx,$seeid,'allversions',\%messages,\%subjects,\%allattachments,\%attachmsgs,\%imsfiles,\$screenname,\$plainname)); |
$r->print(&get_post_contents(\%contrib,$idx,$seeid,'allversions',\%messages,\%subjects,\%allattachments,\%attachmsgs,\%imsfiles,\$screenname,\$plainname,\$showaboutme)); |
} |
} |
$r->print(&Apache::loncommon::end_page()); |
$r->print(&Apache::loncommon::end_page()); |
return OK; |
return OK; |
Line 3934 ENDREDIR
|
Line 4058 ENDREDIR
|
my $entry=$env{'form.like'}?$env{'form.like'}:$env{'form.unlike'}; |
my $entry=$env{'form.like'}?$env{'form.like'}:$env{'form.unlike'}; |
my ($symb,$idx)=split(/\:\:\:/,$entry); |
my ($symb,$idx)=split(/\:\:\:/,$entry); |
($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb); |
($symb,my $feedurl)=&get_feedurl_and_clean_symb($symb); |
|
my $status='OPEN'; |
|
if ($Apache::lonhomework::parsing_a_problem || |
|
$Apache::lonhomework::parsing_a_task) { |
|
$status=$Apache::inputtags::status[-1]; |
|
} |
|
my $result; |
|
my $realsymb = &get_realsymb($symb); |
|
if (&discussion_vote_available($status,$realsymb)) { |
# |
# |
# Likes and unlikes are in db-file "disclikes" of the course |
# Likes and unlikes are in db-file "disclikes" of the course |
# The prefix is the $symb to identify the resource discussion, |
# The prefix is the $symb to identify the resource discussion, |
# and the $idx to identify the entry |
# and the $idx to identify the entry |
# |
# |
my $prefix=$symb.':'.$idx.':'; |
my $prefix=$symb.':'.$idx.':'; |
my %contrib=&Apache::lonnet::dump('disclikes', |
my %contrib=&Apache::lonnet::dump('disclikes', |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.num'}, |
$env{'course.'.$env{'request.course.id'}.'.num'}, |
'^'.$prefix); |
'^'.$prefix); |
# Get all who like or unlike this |
|
my $currentlikers=$contrib{$prefix.'likers'}; |
# Get current like or unlike status for the $idx for this user. |
my $currentunlikers=$contrib{$prefix.'unlikers'}; |
my $thisuser=$env{'user.name'}.':'.$env{'user.domain'}; |
|
my ($userlikes,$userunlikes); |
|
if (ref($contrib{$prefix.'likers'}) eq 'HASH') { |
|
if (exists($contrib{$prefix.'likers'}{$thisuser})) { |
|
$userlikes = 1; |
|
} |
|
} |
|
if (ref($contrib{$prefix.'unlikers'}) eq 'HASH') { |
|
if (exists($contrib{$prefix.'unlikers'}{$thisuser})) { |
|
$userunlikes = 1; |
|
} |
|
} |
# Get the current "likes" count |
# Get the current "likes" count |
my $likes=$contrib{$prefix.'likes'}; |
my $likes=$contrib{$prefix.'likes'}; |
# Find out if they already voted |
# Find out if they already voted |
# Users cannot like a post twice, or unlike it twice. They can change their mind, though |
# Users cannot like a post twice, or unlike it twice. |
my $alreadyflag=0; |
# They can change their mind, though. |
my $thisuser=$env{'user.name'}.':'.$env{'user.domain'}; |
my $alreadyflag=0; |
if ($env{'form.like'}) { |
my $thisuser=$env{'user.name'}.':'.$env{'user.domain'}; |
if ($currentlikers=~/\,\Q$thisuser\E\,/) { |
if ($env{'form.like'}) { |
$alreadyflag=1; |
if ($userlikes) { |
} else { |
$alreadyflag=1; |
if ($currentunlikers=~/\,\Q$thisuser\E\,/) { |
} elsif ($userunlikes) { |
$currentunlikers=~s/\,\Q$thisuser\E\,//g; |
delete($contrib{$prefix.'unlikers'}{$thisuser}); |
|
$likes++; |
} else { |
} else { |
$currentlikers.=','.$thisuser.','; |
if (ref($contrib{$prefix.'likers'}) eq 'HASH') { |
|
$contrib{$prefix.'likers'}{$thisuser} = 1; |
|
} else { |
|
$contrib{$prefix.'likers'} = {$thisuser => 1}; |
|
} |
|
$likes++; |
} |
} |
$likes++; |
|
} |
|
} else { |
|
if ($currentunlikers=~/\,\Q$thisuser\E\,/) { |
|
$alreadyflag=1; |
|
} else { |
} else { |
if ($currentlikers=~/\,\Q$thisuser\E\,/) { |
if ($userunlikes) { |
$currentlikers=~s/\,\Q$thisuser\E\,//g; |
$alreadyflag=1; |
|
} elsif ($userlikes) { |
|
delete($contrib{$prefix.'likers'}{$thisuser}); |
|
$likes--; |
} else { |
} else { |
$currentunlikers.=','.$thisuser.','; |
if (ref($contrib{$prefix.'unlikers'}) eq 'HASH') { |
|
$contrib{$prefix.'unlikers'}{$thisuser} = 1; |
|
} else { |
|
$contrib{$prefix.'unlikers'} = {$thisuser => 1}; |
|
} |
|
$likes--; |
} |
} |
$likes--; |
} |
} |
|
} |
|
my $result; |
|
# $alreadyflag would be 1 if they tried to double-like or double-unlike |
# $alreadyflag would be 1 if they tried to double-like or double-unlike |
unless ($alreadyflag) { |
unless ($alreadyflag) { |
my %newhash=($prefix.'likes' => $likes, |
my %newhash=($prefix.'likes' => $likes, |
$prefix.'likers' => $currentlikers, |
$prefix.'likers' => $contrib{$prefix.'likers'}, |
$prefix.'unlikers' => $currentunlikers); |
$prefix.'unlikers' => $contrib{$prefix.'unlikers'}); |
# Store data in db-file "disclikes" |
# Store data in db-file "disclikes" |
if (&Apache::lonnet::put('disclikes', |
if (&Apache::lonnet::put('disclikes', |
\%newhash, |
\%newhash, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { |
$env{'course.'.$env{'request.course.id'}.'.num'}) eq 'ok') { |
# Also store with the person who posted the liked/unliked entry |
# Also store with the person who posted the liked/unliked entry |
if ($env{'form.like'}) { |
if ($env{'form.like'}) { |
&storediscussionlikes(1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'}); |
&storediscussionlikes(1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'}); |
$result=&mt("Registered 'Like'"); |
$result=&mt("Registered 'Like'"); |
|
} else { |
|
&storediscussionlikes(-1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'}); |
|
$result=&mt("Registered 'Unlike'"); |
|
} |
} else { |
} else { |
&storediscussionlikes(-1,$contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'}); |
|
$result=&mt("Registered 'Unlike'"); |
|
} |
|
} else { |
|
# Oops, something went wrong |
# Oops, something went wrong |
$result=&mt("Failed to register vote"); |
$result=&mt("Failed to register vote"); |
|
} |
} |
} |
|
} else { |
|
$result=&mt('Voting unavailable for this discussion'); |
} |
} |
&redirect_back($r,$feedurl,$result.'<br />', |
&redirect_back($r,$feedurl,$result.'<br />', |
'0','0','','',$env{'form.previous'},undef,undef,undef, |
'0','0','','',$env{'form.previous'},undef,undef,undef, |
Line 4453 None
|
Line 4605 None
|
|
|
=item discussion_visible() |
=item discussion_visible() |
|
|
|
=item discussion_vote_available() |
|
|
|
=item get_realsymb() |
|
|
=item list_discussion() |
=item list_discussion() |
|
|
=item send_feedback_link() |
=item send_feedback_link() |