summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2011-01-04 17:30:57 +0100
committerYorhel <git@yorhel.nl>2011-01-04 17:30:57 +0100
commitd5d55cb04e95fdf9d5185e9f8516e906eeb03831 (patch)
treece9b50520ac3533ace8021ff8149c630dc173a23 /lib
parenta48a7f5b0d4e65a70337d40f7df287810f27d547 (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.pm47
-rw-r--r--lib/VNDB/Handler/Tags.pm66
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};