diff options
author | Yorhel <git@yorhel.nl> | 2011-01-04 17:30:57 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2011-01-04 17:30:57 +0100 |
commit | d5d55cb04e95fdf9d5185e9f8516e906eeb03831 (patch) | |
tree | ce9b50520ac3533ace8021ff8149c630dc173a23 /lib | |
parent | a48a7f5b0d4e65a70337d40f7df287810f27d547 (diff) |
Added checkboxes to VN tagmod and implemented the overrule logic
This finalizes the moderation tag vote overrule. And Damnit, the logic
behind saving the tags to the database isn't fun, I hope I haven't made
any mistakes there.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VNDB/DB/Tags.pm | 47 | ||||
-rw-r--r-- | lib/VNDB/Handler/Tags.pm | 66 |
2 files changed, 77 insertions, 36 deletions
diff --git a/lib/VNDB/DB/Tags.pm b/lib/VNDB/DB/Tags.pm index 623ac10d..b7792eb8 100644 --- a/lib/VNDB/DB/Tags.pm +++ b/lib/VNDB/DB/Tags.pm @@ -202,36 +202,31 @@ sub dbTagLinks { # Change a user's tags for a VN entry -# Arguments: uid, vid, [ [ tag, vote, spoiler ], .. ] sub dbTagLinkEdit { - my($self, $uid, $vid, $new) = @_; - - # compare with the old votes and determine which to delete, and/or insert - my %old = map +($_->{tag}, [ $_->{vote}, $_->{spoiler} // -1 ]), - @{$self->dbTagLinks(vid => $vid, uid => $self->authInfo->{id})}; - my %new = map +($_->[0], [ $_->[1], $_->[2] ]), @$new; - - my(%delete, %update, %insert); - for my $tag (keys %old, keys %new) { - if($old{$tag} && !$new{$tag}) { - $delete{$tag} = 1; - } elsif(!$old{$tag} && $new{$tag}) { - $insert{$tag} = $new{$tag}; - } elsif($old{$tag}[0] != $new{$tag}[0] || $old{$tag}[1] != $new{$tag}[1]) { - $update{$tag} = $new{$tag}; - } - } + my($self, $uid, $vid, $insert, $update, $delete, $overrule) = @_; + + # overrule + # 1. set ignore flag for everyone except $uid + $self->dbExec('UPDATE tags_vn SET ignore = ? WHERE tag = ? AND vid = ? AND uid <> ?', + $overrule->{$_}?1:0, $_, $vid, $uid) for(keys %$overrule); + # 2. make sure $uid isn't ignored when others are set to ignore + # (this happens when a mod takes over an other mods' overrule) + $self->dbExec('UPDATE tags_vn SET ignore = false WHERE tag = ? AND vid = ? AND uid = ?', + $_, $vid, $uid) for(grep $overrule->{$_}, keys %$overrule); + + # delete + $self->dbExec('DELETE FROM tags_vn WHERE vid = ? AND uid = ? AND tag IN(!l)', + $vid, $uid, [ keys %$delete ]) if keys %$delete; - # spoiler '-1' -> NULL - $new{$_}[1] == -1 && ($new{$_}[1] = undef) for keys %new; + # insert + my $val = join ',', map '(?,?,?,?,?,?)', keys %$insert; + $self->dbExec("INSERT INTO tags_vn (tag, vid, uid, vote, spoiler, ignore) VALUES $val", map + +($_, $vid, $uid, $insert->{$_}[0], $insert->{$_}[1]<0?undef:$insert->{$_}[1], $insert->{$_}[2]?1:0), + keys %$insert) if keys %$insert; - # perform the changes - $self->dbExec('DELETE FROM tags_vn WHERE vid = ? AND uid = ? AND tag IN(!l)', - $vid, $uid, [ keys %delete ]) if keys %delete; - $self->dbExec('INSERT INTO tags_vn (tag, vid, uid, vote, spoiler) VALUES (?, ?, ?, ?, ?)', - $_, $vid, $uid, $insert{$_}[0], $insert{$_}[1]) for (keys %insert); + # update $self->dbExec('UPDATE tags_vn SET vote = ?, spoiler = ?, date = NOW() WHERE tag = ? AND vid = ? AND uid = ?', - $update{$_}[0], $update{$_}[1], $_, $vid, $uid) for (keys %update); + $update->{$_}[0], $update->{$_}[1]<0?undef:$update->{$_}[1], $_, $vid, $uid) for (keys %$update); } diff --git a/lib/VNDB/Handler/Tags.pm b/lib/VNDB/Handler/Tags.pm index 7d9b10fa..7fff2a97 100644 --- a/lib/VNDB/Handler/Tags.pm +++ b/lib/VNDB/Handler/Tags.pm @@ -477,19 +477,57 @@ sub vntagmod { return $self->htmlDenied if !$self->authCan('tag'); + my $tags = $self->dbTagStats(vid => $vid, results => 9999); + my $my = $self->dbTagLinks(vid => $vid, uid => $self->authInfo->{id}); + if($self->reqMethod eq 'POST') { return if !$self->authCheckCode; my $frm = $self->formValidate( - { name => 'taglinks', required => 0, default => '', maxlength => 10240, regex => [ qr/^[1-9][0-9]*,-?[1-3],-?[0-2]( [1-9][0-9]*,-?[1-3],-?[0-2])*$/, 'meh' ] } + { name => 'taglinks', required => 0, default => '', maxlength => 10240, regex => [ qr/^[1-9][0-9]*,-?[1-3],-?[0-2]( [1-9][0-9]*,-?[1-3],-?[0-2])*$/, 'meh' ] }, + { name => 'overrule', required => 0, multi => 1, template => 'int' }, ); return 404 if $frm->{_err}; - $self->dbTagLinkEdit($self->authInfo->{id}, $vid, [ map [ split /,/ ], split / /, $frm->{taglinks}]); - } - my $my = $self->dbTagLinks(vid => $vid, uid => $self->authInfo->{id}); - my $tags = $self->dbTagStats(vid => $vid, results => 9999); + # convert some data in a more convenient structure for faster lookup + my %tags = map +($_->{id} => $_), @$tags; + my %old = map +($_->{tag} => $_), @$my; + my %new = map { my($tag, $vote, $spoiler) = split /,/; ($tag => [ $vote, $spoiler ]) } split / /, $frm->{taglinks}; + my %over = !$self->authCan('tagmod') || !$frm->{overrule}[0] ? () : (map $new{$_} ? ($_ => 1) : (), @{$frm->{overrule}}); + + # hashes which need to be filled, indicating what should be changed to the DB + my %delete; # tag => 1 + my %update; # tag => [ vote, spoiler ] (ignore flag is untouched) + my %insert; # tag => [ vote, spoiler, ignore ] + my %overrule; # tag => 0/1 + + for my $t (keys %old, keys %new) { + my $prev_over = $old{$t} && !$old{$t}{ignore} && $tags{$t}{overruled}; + + # overrule checkbox has changed? make sure to (de-)overrule the tag votes + $overrule{$t} = $over{$t}?1:0 if (!$prev_over && $over{$t}) || ($prev_over && !$over{$t}); + + # tag deleted? + if($old{$t} && !$new{$t}) { + $delete{$t} = 1; + next; + } + + # and insert or update the vote + if(!$old{$t} && $new{$t}) { + # determine whether this vote is going to be ignored or not + my $ign = $tags{$t}{overruled} && !$prev_over && !$over{$t}; + $insert{$t} = [ $new{$t}[0], $new{$t}[1], $ign ]; + } elsif($old{$t}{vote} != $new{$t}[0] || (defined $old{$t}{spoiler} ? $old{$t}{spoiler} : -1) != $new{$t}[1]) { + $update{$t} = [ $new{$t}[0], $new{$t}[1] ]; + } + } + $self->dbTagLinkEdit($self->authInfo->{id}, $vid, \%insert, \%update, \%delete, \%overrule); + + # need to re-fetch the tags and tag links, as these have been modified + $tags = $self->dbTagStats(vid => $vid, results => 9999); + $my = $self->dbTagLinks(vid => $vid, uid => $self->authInfo->{id}); + } - my $frm; my $title = mt '_tagv_title', $v->{title}; $self->htmlHeader(title => $title, noindex => 1); @@ -505,19 +543,20 @@ sub vntagmod { end; end; end; - $self->htmlForm({ frm => $frm, action => "/v$vid/tagmod", nosubmit => 1 }, tagmod => [ mt('_tagv_frm_title'), + $self->htmlForm({ action => "/v$vid/tagmod", nosubmit => 1 }, tagmod => [ mt('_tagv_frm_title'), [ hidden => short => 'taglinks', value => '' ], [ static => nolabel => 1, content => sub { table class => 'tgl'; thead; Tr; td ''; - td colspan => 2, class => 'tc_you', mt '_tagv_col_you'; + td colspan => $self->authCan('tagmod') ? 3 : 2, class => 'tc_you', mt '_tagv_col_you'; td colspan => 3, class => 'tc_others', mt '_tagv_col_others'; end; Tr; td class => 'tc_tagname', mt '_tagv_col_tag'; td class => 'tc_myvote', mt '_tagv_col_rating'; + td class => 'tc_myover', 'O' if $self->authCan('tagmod'); td class => 'tc_myspoil', mt '_tagv_col_spoiler'; td class => 'tc_allvote', mt '_tagv_col_rating'; td class => 'tc_allspoil', mt '_tagv_col_spoiler'; @@ -541,10 +580,17 @@ sub vntagmod { Tr id => "tgl_$t->{id}"; td class => 'tc_tagname'; a href => "/g$t->{id}", $t->{name}; end; td class => 'tc_myvote', $m->{vote}||0; + if($self->authCan('tagmod')) { + td class => 'tc_myover'; + input type => 'checkbox', name => 'overrule', value => $t->{id}, + $m->{vote} && !$m->{ignore} && $t->{overruled} ? (checked => 'checked') : () + if $t->{cnt} > 1; + end; + } td class => 'tc_myspoil', defined $m->{spoiler} ? $m->{spoiler} : -1; td class => 'tc_allvote'; - tagscore !$m->{vote} ? $t->{rating} : $t->{cnt} == 1 ? 0 : ($t->{rating}*$t->{cnt} - $m->{vote}) / ($t->{cnt}-1); - i $t->{overruled} ? (class => 'grayedout') : (), ' ('.($t->{cnt} - ($m->{vote} ? 1 : 0)).')'; + tagscore $t->{rating}; + i $t->{overruled} ? (class => 'grayedout') : (), " ($t->{cnt})"; b class => 'standout', style => 'font-weight: bold', ' !' if $t->{overruled}; end; td class => 'tc_allspoil', sprintf '%.2f', $t->{spoiler}; |