--- loncom/interface/lonfeedback.pm 2012/01/10 00:54:05 1.331 +++ loncom/interface/lonfeedback.pm 2012/03/09 15:02:31 1.338 @@ -1,7 +1,7 @@ # The LearningOnline Network # Feedback # -# $Id: lonfeedback.pm,v 1.331 2012/01/10 00:54:05 www Exp $ +# $Id: lonfeedback.pm,v 1.338 2012/03/09 15:02:31 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -955,6 +955,9 @@ sub build_posting_display { my $thisuser=$env{'user.name'}.':'.$env{'user.domain'}; # Array with likes to figure out averages, etc. my @theselikes=(); +# Hashes containing likes and unlikes for this user. + my %userlikes=(); + my %userunlikes=(); # Is the user allowed to see the real name behind anonymous postings? my $see_anonymous = &Apache::lonnet::allowed('rin',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')); @@ -994,10 +997,23 @@ sub build_posting_display { next if ($contrib{$idx.':deleted'}); next if ($contrib{$idx.':hidden'}); 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 discussions to warrant that +# Figure out average likes and standard deviation if there are enough +# discussions to warrant that my $ave=0; my $stddev=10000; if ($#theselikes>1) { @@ -1019,10 +1035,9 @@ sub build_posting_display { my $twoplus=$ave+2.*$stddev; my $oneminus=$ave-$stddev; my $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 -# +# for (my $id=1;$id<=$contrib{'version'};$id++) { my $idx=$id; next if ($contrib{$idx.':deleted'}); @@ -1072,7 +1087,7 @@ sub build_posting_display { my %subjects = (); my %attachtxt = (); my %allattachments = (); - my ($screenname,$plainname); + my ($screenname,$plainname,$showaboutme); 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. @@ -1082,7 +1097,7 @@ sub build_posting_display { $$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); + &get_post_contents(\%contrib,$idx,$seeid,$outputtarget,\%messages,\%subjects,\%allattachments,\%attachtxt,$imsfiles,\$screenname,\$plainname,\$showaboutme,$numoldver); # Set up for sorting by subject @@ -1112,12 +1127,18 @@ sub build_posting_display { } } if (!$contrib{$idx.':anonymous'} || $see_anonymous) { - $sender=&Apache::loncommon::aboutmewrapper( - $plainname, - $contrib{$idx.':sendername'}, - $contrib{$idx.':senderdomain'}).' ('. - $contrib{$idx.':sendername'}.':'. - $contrib{$idx.':senderdomain'}.')'; + if ($showaboutme) { + $sender = &Apache::loncommon::aboutmewrapper( + $plainname, + $contrib{$idx.':sendername'}, + $contrib{$idx.':senderdomain'}); + } else { + $sender = $plainname; + } + if ($see_anonymous) { + $sender .= ' ('.$contrib{$idx.':sendername'}.':'. + $contrib{$idx.':senderdomain'}.')'; + } $sender = ''.$sender.''; if ($contrib{$idx.':anonymous'}) { $sender.=' ['.$$anonhash{$key}.'] '. @@ -1156,18 +1177,12 @@ sub build_posting_display { @{$$namesort{$lastname}{$firstname}} = ("$idx"); } if ($outputtarget ne 'tex') { - unless ($likes{$symb.':'.$idx.':likers'}=~/\,\Q$thisuser\E\,/) { - $sender.=' '.&discussion_link($symb,''.&mt('Like').'','like',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Like this posting")); - } - unless ($likes{$symb.':'.$idx.':unlikers'}=~/\,\Q$thisuser\E\,/) { - $sender.=' '.&discussion_link($symb,''.&mt('Unlike').'',,'unlike',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Unlike this posting")); - } - my $thislikes=$likes{$symb.':'.$idx.':likes'}; - if ($thislikes>0) { - $sender.=' ('.&mt("[_1] likes",$thislikes).')'; - } elsif ($thislikes<0) { - $sender.=' ('.&mt("[_1] unlikes",abs($thislikes)).')'; +# Add karma stars + my $karma=&userkarma($contrib{$idx.':sendername'},$contrib{$idx.':senderdomain'}); + for (my $i=1;$i<=$karma;$i++) { + $sender.=''.&mt('Contributor Kudos').''; } +# Can people edit this? if (&editing_allowed($escsymb.':::'.$idx,$group)) { if (($env{'user.domain'} eq $contrib{$idx.':senderdomain'}) && ($env{'user.name'} eq $contrib{$idx.':sendername'})) { $sender.=' '. @@ -1363,13 +1378,32 @@ sub build_posting_display { } elsif ($thislikes<$oneminus) { $likesize="75"; } +# Actually glue in the message itself $$discussionitems[$idx].= '
'. "
". $message. '
'; +# Put in the like and unlike buttons + if ($userlikes{$idx}) { + $$discussionitems[$idx].=''.&mt('You like this posting').''; + } else { + $$discussionitems[$idx].=' '.&discussion_link($symb,''.&mt('Like').'','like',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Like this posting")); + } + if ($userunlikes{$idx}) { + $$discussionitems[$idx].=''.&mt('You unlike this posting').''; + } else { + $$discussionitems[$idx].=' '.&discussion_link($symb,''.&mt('Unlike').'','unlike',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Unlike this posting")); + } + 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'}) { 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) { $$discussionitems[$idx] .= '  '. &discussion_link($symb,&mt('Display all versions'),'allversions',$idx,$$newpostsflag,$prevread,&group_args($group)); @@ -1456,7 +1490,7 @@ sub filter_regexp { 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 $start=$numver; my $end=$numver + 1; @@ -1474,13 +1508,20 @@ sub get_post_contents { $$contrib{$idx.':sendername'}, $$contrib{$idx.':senderdomain'}); $$screenname=$$contrib{$idx.':screenname'}; - - my $sender=&Apache::loncommon::aboutmewrapper( + $$showaboutme = &Apache::lonnet::usertools_access($$contrib{$idx.':sendername'}, + $$contrib{$idx.':senderdomain'}, + 'aboutme'); + my $sender = $$plainname; + if ($$showaboutme) { + $sender = &Apache::loncommon::aboutmewrapper( $$plainname, $$contrib{$idx.':sendername'}, - $$contrib{$idx.':senderdomain'}).' ('. - $$contrib{$idx.':sendername'}.':'. - $$contrib{$idx.':senderdomain'}.')'; + $$contrib{$idx.':senderdomain'}); + } + if ($seeid) { + $sender .= ' ('.$$contrib{$idx.':sendername'}.':'. + $$contrib{$idx.':senderdomain'}.')'; + } my $attachmenturls = $$contrib{$idx.':attachmenturl'}; my @postversions = (); if ($type eq 'allversions' || $type eq 'export') { @@ -2683,7 +2724,7 @@ sub no_redirect_back { 'add_entries' => \%onload,); if ($feedurl !~ m{^/adm/feedback}) { - $body_options{'rediect'} = [2,$feedurl]; + $body_options{'redirect'} = [2,$feedurl]; } my $start_page= &Apache::loncommon::start_page('Feedback not sent',undef, @@ -3065,6 +3106,7 @@ sub adddiscuss { $newrecord{'subnumber'}=$record{'subnumber'}+1; $status.='
'.&mt('Registering').': '. &Apache::lonnet::cstore(\%newrecord,'_discussion'); + &updatekarma(); } } else { $status.='Failed.'; @@ -3112,6 +3154,27 @@ sub updatekarma { 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 @@ -3148,7 +3211,11 @@ sub storediscussionlikes { 'likes' => $likes, 'totallikes' => $totallikes, 'totalvotes' => $totalvotes); - return &Apache::lonnet::cstore(\%newrecord,'_discussion',$course,$udom,$uname); + my $status=&Apache::lonnet::cstore(\%newrecord,'_discussion',$course,$udom,$uname); + if ($status eq 'ok') { + &updatekarma($uname,$udom,$course); + } + return $status; } sub get_discussion_info { @@ -3436,14 +3503,13 @@ sub generate_attachments_button { my ($idx,$attachnum,$ressymb,$now,$currnewattach,$deloldattach, $numoldver,$mode,$blockblog) = @_; my $origpage = $ENV{'REQUEST_URI'}; - my $att=$attachnum.' '.&mt("attachments"); my %lt = &Apache::lonlocal::texthash( - 'clic' => 'Click to add/remove attachments', + 'clic' => 'Add/remove attachments', ); my $response = (<
-$lt{'clic'}:  1}; } $likes++; - } + } } else { - if ($currentunlikers=~/\,\Q$thisuser\E\,/) { + if ($userunlikes) { $alreadyflag=1; + } elsif ($userlikes) { + delete($contrib{$prefix.'likers'}{$thisuser}); + $likes--; } else { - if ($currentlikers=~/\,\Q$thisuser\E\,/) { - $currentlikers=~s/\,\Q$thisuser\E\,//g; + if (ref($contrib{$prefix.'unlikers'}) eq 'HASH') { + $contrib{$prefix.'unlikers'}{$thisuser} = 1; } else { - $currentunlikers.=','.$thisuser.','; + $contrib{$prefix.'unlikers'} = {$thisuser => 1}; } $likes--; - } + } } my $result; # $alreadyflag would be 1 if they tried to double-like or double-unlike unless ($alreadyflag) { my %newhash=($prefix.'likes' => $likes, - $prefix.'likers' => $currentlikers, - $prefix.'unlikers' => $currentunlikers); + $prefix.'likers' => $contrib{$prefix.'likers'}, + $prefix.'unlikers' => $contrib{$prefix.'unlikers'}); # Store data in db-file "disclikes" if (&Apache::lonnet::put('disclikes', \%newhash,