--- loncom/interface/lonfeedback.pm 2012/03/07 00:02:10 1.337 +++ 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.337 2012/03/07 00:02:10 raeburn 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) { @@ -1021,7 +1037,7 @@ sub build_posting_display { my $twominus=$ave-2.*$stddev; # # 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'}); @@ -1368,15 +1384,15 @@ sub build_posting_display { $message. ''; # Put in the like and unlike buttons - unless ($likes{$symb.':'.$idx.':likers'}=~/\,\Q$thisuser\E\,/) { - $$discussionitems[$idx].=' '.&discussion_link($symb,''.&mt('Like').'','like',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Like this posting")); - } else { + if ($userlikes{$idx}) { $$discussionitems[$idx].=''.&mt('You like this posting').''; - } - unless ($likes{$symb.':'.$idx.':unlikers'}=~/\,\Q$thisuser\E\,/) { - $$discussionitems[$idx].=' '.&discussion_link($symb,''.&mt('Unlike').'','unlike',$idx,$$newpostsflag,$prevread,&group_args($group),&mt("Unlike 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) { @@ -4019,44 +4035,62 @@ ENDREDIR $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'}, '^'.$prefix); -# Get all who like or unlike this - my $currentlikers=$contrib{$prefix.'likers'}; - my $currentunlikers=$contrib{$prefix.'unlikers'}; + +# Get current like or unlike status for the $idx for this user. + 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 my $likes=$contrib{$prefix.'likes'}; # 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. +# They can change their mind, though. my $alreadyflag=0; my $thisuser=$env{'user.name'}.':'.$env{'user.domain'}; if ($env{'form.like'}) { - if ($currentlikers=~/\,\Q$thisuser\E\,/) { + if ($userlikes) { $alreadyflag=1; + } elsif ($userunlikes) { + delete($contrib{$prefix.'unlikers'}{$thisuser}); + $likes++; } else { - if ($currentunlikers=~/\,\Q$thisuser\E\,/) { - $currentunlikers=~s/\,\Q$thisuser\E\,//g; + if (ref($contrib{$prefix.'likers'}) eq 'HASH') { + $contrib{$prefix.'likers'}{$thisuser} = 1; } else { - $currentlikers.=','.$thisuser.','; + $contrib{$prefix.'likers'} = {$thisuser => 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,