From 120b63d507a3316666b25494bc890a024948aef8 Mon Sep 17 00:00:00 2001 From: Max Kanat-Alexander Date: Mon, 15 Feb 2010 15:22:55 -0800 Subject: Bug 372979: Make voting into an extension r=mkanat, a=mkanat, a=LpSolit --- Bugzilla/Bug.pm | 158 +---------------------------------------- Bugzilla/BugMail.pm | 11 +-- Bugzilla/Comment.pm | 2 +- Bugzilla/Config/BugFields.pm | 6 -- Bugzilla/Constants.pm | 8 +-- Bugzilla/DB/Schema.pm | 27 ------- Bugzilla/Field.pm | 1 - Bugzilla/Install/DB.pm | 54 +++++++------- Bugzilla/Object.pm | 3 +- Bugzilla/Product.pm | 147 -------------------------------------- Bugzilla/Search.pm | 18 +---- Bugzilla/Search/Quicksearch.pm | 18 ----- Bugzilla/WebService/Bug.pm | 10 +-- 13 files changed, 43 insertions(+), 420 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 336b9cfe1..b3f0fe58e 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -57,7 +57,6 @@ use URI::QueryParam; use base qw(Bugzilla::Object Exporter); @Bugzilla::Bug::EXPORT = qw( bug_alias_to_id - RemoveVotes CheckIfVotedConfirmed LogActivityEntry editable_bug_fields ); @@ -631,7 +630,6 @@ sub run_create_validators { # You can't set these fields on bug creation (or sometimes ever). delete $params->{resolution}; - delete $params->{votes}; delete $params->{lastdiffed}; delete $params->{bug_id}; @@ -967,7 +965,6 @@ sub remove_from_db { # - flags # - keywords # - longdescs - # - votes # Also, the attach_data table uses attachments.attach_id as a foreign # key, and so indirectly depends on a bug deletion too. @@ -983,7 +980,6 @@ sub remove_from_db { undef, ($bug_id, $bug_id)); $dbh->do("DELETE FROM flags WHERE bug_id = ?", undef, $bug_id); $dbh->do("DELETE FROM keywords WHERE bug_id = ?", undef, $bug_id); - $dbh->do("DELETE FROM votes WHERE bug_id = ?", undef, $bug_id); # The attach_data table doesn't depend on bugs.bug_id directly. my $attach_ids = @@ -1819,7 +1815,7 @@ sub fields { bug_status resolution dup_id see_also bug_file_loc status_whiteboard keywords priority bug_severity target_milestone - dependson blocked votes everconfirmed + dependson blocked everconfirmed reporter assigned_to cc estimated_time remaining_time actual_time deadline), @@ -2870,14 +2866,6 @@ sub show_attachment_flags { return $self->{'show_attachment_flags'}; } -sub use_votes { - my ($self) = @_; - return 0 if $self->{'error'}; - - return Bugzilla->params->{'usevotes'} - && $self->product_obj->votes_per_user > 0; -} - sub groups { my $self = shift; return $self->{'groups'} if exists $self->{'groups'}; @@ -3019,20 +3007,6 @@ sub choices { return $self->{'choices'}; } -sub votes { - my ($self) = @_; - return 0 if $self->{error}; - return $self->{votes} if defined $self->{votes}; - - my $dbh = Bugzilla->dbh; - $self->{votes} = $dbh->selectrow_array( - 'SELECT SUM(vote_count) FROM votes - WHERE bug_id = ? ' . $dbh->sql_group_by('bug_id'), - undef, $self->bug_id); - $self->{votes} ||= 0; - return $self->{votes}; -} - # Convenience Function. If you need speed, use this. If you need # other Bug fields in addition to this, just create a new Bug with # the alias. @@ -3312,136 +3286,6 @@ sub CountOpenDependencies { return @dependencies; } -# If a bug is moved to a product which allows less votes per bug -# compared to the previous product, extra votes need to be removed. -sub RemoveVotes { - my ($id, $who, $reason) = (@_); - my $dbh = Bugzilla->dbh; - - my $whopart = ($who) ? " AND votes.who = $who" : ""; - - my $sth = $dbh->prepare("SELECT profiles.login_name, " . - "profiles.userid, votes.vote_count, " . - "products.votesperuser, products.maxvotesperbug " . - "FROM profiles " . - "LEFT JOIN votes ON profiles.userid = votes.who " . - "LEFT JOIN bugs ON votes.bug_id = bugs.bug_id " . - "LEFT JOIN products ON products.id = bugs.product_id " . - "WHERE votes.bug_id = ? " . $whopart); - $sth->execute($id); - my @list; - while (my ($name, $userid, $oldvotes, $votesperuser, $maxvotesperbug) = $sth->fetchrow_array()) { - push(@list, [$name, $userid, $oldvotes, $votesperuser, $maxvotesperbug]); - } - - # @messages stores all emails which have to be sent, if any. - # This array is passed to the caller which will send these emails itself. - my @messages = (); - - if (scalar(@list)) { - foreach my $ref (@list) { - my ($name, $userid, $oldvotes, $votesperuser, $maxvotesperbug) = (@$ref); - - $maxvotesperbug = min($votesperuser, $maxvotesperbug); - - # If this product allows voting and the user's votes are in - # the acceptable range, then don't do anything. - next if $votesperuser && $oldvotes <= $maxvotesperbug; - - # If the user has more votes on this bug than this product - # allows, then reduce the number of votes so it fits - my $newvotes = $maxvotesperbug; - - my $removedvotes = $oldvotes - $newvotes; - - if ($newvotes) { - $dbh->do("UPDATE votes SET vote_count = ? " . - "WHERE bug_id = ? AND who = ?", - undef, ($newvotes, $id, $userid)); - } else { - $dbh->do("DELETE FROM votes WHERE bug_id = ? AND who = ?", - undef, ($id, $userid)); - } - - # Notice that we did not make sure that the user fit within the $votesperuser - # range. This is considered to be an acceptable alternative to losing votes - # during product moves. Then next time the user attempts to change their votes, - # they will be forced to fit within the $votesperuser limit. - - # Now lets send the e-mail to alert the user to the fact that their votes have - # been reduced or removed. - my $vars = { - 'to' => $name . Bugzilla->params->{'emailsuffix'}, - 'bugid' => $id, - 'reason' => $reason, - - 'votesremoved' => $removedvotes, - 'votesold' => $oldvotes, - 'votesnew' => $newvotes, - }; - - my $voter = new Bugzilla::User($userid); - my $template = Bugzilla->template_inner($voter->settings->{'lang'}->{'value'}); - - my $msg; - $template->process("email/votes-removed.txt.tmpl", $vars, \$msg); - push(@messages, $msg); - } - Bugzilla->template_inner(""); - - my $votes = $dbh->selectrow_array("SELECT SUM(vote_count) " . - "FROM votes WHERE bug_id = ?", - undef, $id) || 0; - $dbh->do("UPDATE bugs SET votes = ? WHERE bug_id = ?", - undef, ($votes, $id)); - } - # Now return the array containing emails to be sent. - return @messages; -} - -# If a user votes for a bug, or the number of votes required to -# confirm a bug has been reduced, check if the bug is now confirmed. -sub CheckIfVotedConfirmed { - my $id = shift; - my $bug = new Bugzilla::Bug($id); - - my $ret = 0; - if (!$bug->everconfirmed - and $bug->product_obj->votes_to_confirm - and $bug->votes >= $bug->product_obj->votes_to_confirm) - { - $bug->add_comment('', { type => CMT_POPULAR_VOTES }); - - if ($bug->bug_status eq 'UNCONFIRMED') { - # Get a valid open state. - my $new_status; - foreach my $state (@{$bug->status->can_change_to}) { - if ($state->is_open && $state->name ne 'UNCONFIRMED') { - $new_status = $state->name; - last; - } - } - ThrowCodeError('no_open_bug_status') unless $new_status; - - # We cannot call $bug->set_status() here, because a user without - # canconfirm privs should still be able to confirm a bug by - # popular vote. We already know the new status is valid, so it's safe. - $bug->{bug_status} = $new_status; - $bug->{everconfirmed} = 1; - delete $bug->{'status'}; # Contains the status object. - } - else { - # If the bug is in a closed state, only set everconfirmed to 1. - # Do not call $bug->_set_everconfirmed(), for the same reason as above. - $bug->{everconfirmed} = 1; - } - $bug->update(); - - $ret = 1; - } - return $ret; -} - ################################################################################ # check_can_change_field() defines what users are allowed to change. You # can add code here for site-specific policy changes, according to the diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm index 204c4ba9a..e7694c32e 100644 --- a/Bugzilla/BugMail.pm +++ b/Bugzilla/BugMail.pm @@ -377,12 +377,6 @@ sub Send { # the relationships in a hash. The keys are userids, the values are an # array of role constants. - # Voters - my $voters = $dbh->selectcol_arrayref( - "SELECT who FROM votes WHERE bug_id = ?", undef, ($id)); - - $recipients{$_}->{+REL_VOTER} = BIT_DIRECT foreach (@$voters); - # CCs $recipients{$_}->{+REL_CC} = BIT_DIRECT foreach (@ccs); @@ -405,8 +399,8 @@ sub Send { foreach my $ref (@$diffs) { my ($who, $whoname, $what, $when, $old, $new) = (@$ref); if ($old) { - # You can't stop being the reporter, and mail isn't sent if you - # remove your vote. + # You can't stop being the reporter, so we don't check that + # relationship here. # Ignore people whose user account has been deleted or renamed. if ($what eq "CC") { foreach my $cc_user (split(/[\s,]+/, $old)) { @@ -462,7 +456,6 @@ sub Send { foreach my $user_id (keys %recipients) { my %rels_which_want; my $sent_mail = 0; - my $user = new Bugzilla::User($user_id); # Deleted users must be excluded. next unless $user; diff --git a/Bugzilla/Comment.pm b/Bugzilla/Comment.pm index 300357313..60d26012f 100644 --- a/Bugzilla/Comment.pm +++ b/Bugzilla/Comment.pm @@ -148,7 +148,7 @@ sub set_type { sub _check_extra_data { my ($invocant, $extra_data, $type) = @_; $type = $invocant->type if ref $invocant; - if ($type == CMT_NORMAL or $type == CMT_POPULAR_VOTES) { + if ($type == CMT_NORMAL) { if (defined $extra_data) { ThrowCodeError('comment_extra_data_not_allowed', { type => $type, extra_data => $extra_data }); diff --git a/Bugzilla/Config/BugFields.pm b/Bugzilla/Config/BugFields.pm index 9f3ddc9ab..d0de9dac6 100644 --- a/Bugzilla/Config/BugFields.pm +++ b/Bugzilla/Config/BugFields.pm @@ -71,12 +71,6 @@ sub get_param_list { default => 0 }, - { - name => 'usevotes', - type => 'b', - default => 0 - }, - { name => 'usebugaliases', type => 'b', diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 8ab7455ff..d626c9749 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -90,7 +90,6 @@ use File::Basename; CMT_NORMAL CMT_DUPE_OF CMT_HAS_DUPE - CMT_POPULAR_VOTES CMT_MOVED_TO CMT_ATTACHMENT_CREATED CMT_ATTACHMENT_UPDATED @@ -98,7 +97,7 @@ use File::Basename; THROW_ERROR RELATIONSHIPS - REL_ASSIGNEE REL_QA REL_REPORTER REL_CC REL_VOTER REL_GLOBAL_WATCHER + REL_ASSIGNEE REL_QA REL_REPORTER REL_CC REL_GLOBAL_WATCHER REL_ANY POS_EVENTS @@ -282,7 +281,7 @@ use constant MAX_COMMENT_LENGTH => 65535; use constant CMT_NORMAL => 0; use constant CMT_DUPE_OF => 1; use constant CMT_HAS_DUPE => 2; -use constant CMT_POPULAR_VOTES => 3; +# Type 3 was CMT_POPULAR_VOTES, which moved to the Voting extension. use constant CMT_MOVED_TO => 4; use constant CMT_ATTACHMENT_CREATED => 5; use constant CMT_ATTACHMENT_UPDATED => 6; @@ -295,7 +294,7 @@ use constant REL_ASSIGNEE => 0; use constant REL_QA => 1; use constant REL_REPORTER => 2; use constant REL_CC => 3; -use constant REL_VOTER => 4; +# REL 4 was REL_VOTER, before it was moved ino an extension. use constant REL_GLOBAL_WATCHER => 5; # We need these strings for the X-Bugzilla-Reasons header @@ -307,7 +306,6 @@ use constant RELATIONSHIPS => { REL_REPORTER , "Reporter", REL_QA , "QAcontact", REL_CC , "CC", - REL_VOTER , "Voter", REL_GLOBAL_WATCHER, "GlobalWatcher" }; diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm index 27ae3be8a..21c0e7970 100644 --- a/Bugzilla/DB/Schema.pm +++ b/Bugzilla/DB/Schema.pm @@ -273,8 +273,6 @@ use constant ABSTRACT_SCHEMA => { COLUMN => 'userid'}}, status_whiteboard => {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}, - votes => {TYPE => 'INT3', NOTNULL => 1, - DEFAULT => '0'}, # Note: keywords field is only a cache; the real data # comes from the keywords table keywords => {TYPE => 'MEDIUMTEXT', NOTNULL => 1, @@ -309,7 +307,6 @@ use constant ABSTRACT_SCHEMA => { bugs_resolution_idx => ['resolution'], bugs_target_milestone_idx => ['target_milestone'], bugs_qa_contact_idx => ['qa_contact'], - bugs_votes_idx => ['votes'], ], }, @@ -434,24 +431,6 @@ use constant ABSTRACT_SCHEMA => { ], }, - votes => { - FIELDS => [ - who => {TYPE => 'INT3', NOTNULL => 1, - REFERENCES => {TABLE => 'profiles', - COLUMN => 'userid', - DELETE => 'CASCADE'}}, - bug_id => {TYPE => 'INT3', NOTNULL => 1, - REFERENCES => {TABLE => 'bugs', - COLUMN => 'bug_id', - DELETE => 'CASCADE'}}, - vote_count => {TYPE => 'INT2', NOTNULL => 1}, - ], - INDEXES => [ - votes_who_idx => ['who'], - votes_bug_id_idx => ['bug_id'], - ], - }, - attachments => { FIELDS => [ attach_id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, @@ -1223,12 +1202,6 @@ use constant ABSTRACT_SCHEMA => { description => {TYPE => 'MEDIUMTEXT'}, isactive => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 1}, - votesperuser => {TYPE => 'INT2', NOTNULL => 1, - DEFAULT => 0}, - maxvotesperbug => {TYPE => 'INT2', NOTNULL => 1, - DEFAULT => '10000'}, - votestoconfirm => {TYPE => 'INT2', NOTNULL => 1, - DEFAULT => 0}, defaultmilestone => {TYPE => 'varchar(20)', NOTNULL => 1, DEFAULT => "'---'"}, allows_unconfirmed => {TYPE => 'BOOLEAN', NOTNULL => 1, diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm index 17e4194c2..c2ab6e11b 100644 --- a/Bugzilla/Field.pm +++ b/Bugzilla/Field.pm @@ -188,7 +188,6 @@ use constant DEFAULT_FIELDS => ( buglist => 1}, {name => 'reporter', desc => 'ReportedBy', in_new_bugmail => 1, buglist => 1}, - {name => 'votes', desc => 'Votes', buglist => 1}, {name => 'qa_contact', desc => 'QAContact', in_new_bugmail => 1, buglist => 1}, {name => 'cc', desc => 'CC', in_new_bugmail => 1}, diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm index 65137e593..66461bf45 100644 --- a/Bugzilla/Install/DB.pm +++ b/Bugzilla/Install/DB.pm @@ -168,11 +168,6 @@ sub update_table_definitions { $dbh->bz_add_column('bugs', 'everconfirmed', {TYPE => 'BOOLEAN', NOTNULL => 1}, 1); - $dbh->bz_add_column('products', 'maxvotesperbug', - {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '10000'}); - $dbh->bz_add_column('products', 'votestoconfirm', - {TYPE => 'INT2', NOTNULL => 1}, 0); - _populate_milestones_table(); # 2000-03-22 Changed the default value for target_milestone to be "---" @@ -363,8 +358,10 @@ sub update_table_definitions { {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); $dbh->bz_alter_column('bugs', 'keywords', {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); - $dbh->bz_alter_column('bugs', 'votes', - {TYPE => 'INT3', NOTNULL => 1, DEFAULT => '0'}); + if ($dbh->bz_column_info('bugs', 'votes')) { + $dbh->bz_alter_column('bugs', 'votes', + {TYPE => 'INT3', NOTNULL => 1, DEFAULT => '0'}); + } $dbh->bz_alter_column('bugs', 'lastdiffed', {TYPE => 'DATETIME'}); @@ -469,11 +466,14 @@ sub update_table_definitions { if ($dbh->bz_column_info('products', 'disallownew')){ $dbh->bz_alter_column('products', 'disallownew', {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0}); + + if ($dbh->bz_column_info('products', 'votesperuser')) { + $dbh->bz_alter_column('products', 'votesperuser', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); + $dbh->bz_alter_column('products', 'votestoconfirm', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); + } } - $dbh->bz_alter_column('products', 'votesperuser', - {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); - $dbh->bz_alter_column('products', 'votestoconfirm', - {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); # 2006-08-04 LpSolit@gmail.com - Bug 305941 $dbh->bz_drop_column('profiles', 'refreshed_when'); @@ -654,14 +654,14 @@ sub _add_bug_vote_cache { # (P.S. All is not lost; it appears that the latest betas of MySQL # support a new table format which will allow 32 indices.) - $dbh->bz_drop_column('bugs', 'area'); - if (!$dbh->bz_column_info('bugs', 'votes')) { + if ($dbh->bz_column_info('bugs', 'area')) { + $dbh->bz_drop_column('bugs', 'area'); $dbh->bz_add_column('bugs', 'votes', {TYPE => 'INT3', NOTNULL => 1, DEFAULT => 0}); $dbh->bz_add_index('bugs', 'bugs_votes_idx', [qw(votes)]); + $dbh->bz_add_column('products', 'votesperuser', + {TYPE => 'INT2', NOTNULL => 1}, 0); } - $dbh->bz_add_column('products', 'votesperuser', - {TYPE => 'INT2', NOTNULL => 1}, 0); } sub _update_product_name_definition { @@ -896,9 +896,11 @@ sub _add_unique_login_name_index_to_profiles { ["votes", "who"], ["longdescs", "who"]) { my ($table, $field) = (@$i); - print " Updating $table.$field...\n"; - $dbh->do("UPDATE $table SET $field = $u1 " . - "WHERE $field = $u2"); + if ($dbh->bz_table_info($table)) { + print " Updating $table.$field...\n"; + $dbh->do("UPDATE $table SET $field = $u1 " . + "WHERE $field = $u2"); + } } $dbh->do("DELETE FROM profiles WHERE userid = $u2"); } @@ -2206,9 +2208,9 @@ sub _rename_votes_count_and_force_group_refresh { # # Renaming the 'count' column in the votes table because Sybase doesn't # like it - if ($dbh->bz_column_info('votes', 'count')) { - $dbh->bz_rename_column('votes', 'count', 'vote_count'); - } + return if !$dbh->bz_table_info('votes'); + return if $dbh->bz_column_info('votes', 'count'); + $dbh->bz_rename_column('votes', 'count', 'vote_count'); } sub _fix_group_with_empty_name { @@ -2266,7 +2268,9 @@ sub _migrate_email_prefs_to_new_table { "Reporter" => REL_REPORTER, "QAcontact" => REL_QA, "CClist" => REL_CC, - "Voter" => REL_VOTER); + # REL_VOTER was "4" before it was moved to an + # extension. + "Voter" => 4); my %events = ("Removeme" => EVT_ADDED_REMOVED, "Comments" => EVT_COMMENT, @@ -3343,8 +3347,10 @@ sub _add_allows_unconfirmed_to_product_table { if (!$dbh->bz_column_info('products', 'allows_unconfirmed')) { $dbh->bz_add_column('products', 'allows_unconfirmed', { TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE' }); - $dbh->do('UPDATE products SET allows_unconfirmed = 1 - WHERE votestoconfirm > 0'); + if ($dbh->bz_column_info('products', 'votestoconfirm')) { + $dbh->do('UPDATE products SET allows_unconfirmed = 1 + WHERE votestoconfirm > 0'); + } } } diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm index dac8962ff..11db7567b 100644 --- a/Bugzilla/Object.pm +++ b/Bugzilla/Object.pm @@ -278,7 +278,8 @@ sub set { my ($self, $field, $value) = @_; # This method is protected. It's used to help implement set_ functions. - caller->isa('Bugzilla::Object') + my $caller = caller; + $caller->isa('Bugzilla::Object') || $caller->isa('Bugzilla::Extension') || ThrowCodeError('protection_violation', { caller => caller, superclass => __PACKAGE__, diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm index 6b00fcbf6..975af7d5d 100644 --- a/Bugzilla/Product.pm +++ b/Bugzilla/Product.pm @@ -48,9 +48,6 @@ use constant DB_COLUMNS => qw( classification_id description isactive - votesperuser - maxvotesperbug - votestoconfirm defaultmilestone allows_unconfirmed ); @@ -66,9 +63,6 @@ use constant UPDATE_COLUMNS => qw( description defaultmilestone isactive - votesperuser - maxvotesperbug - votestoconfirm allows_unconfirmed ); @@ -80,9 +74,6 @@ use constant VALIDATORS => { version => \&_check_version, defaultmilestone => \&_check_default_milestone, isactive => \&Bugzilla::Object::check_boolean, - votesperuser => \&_check_votes_per_user, - maxvotesperbug => \&_check_votes_per_bug, - votestoconfirm => \&_check_votes_to_confirm, create_series => \&Bugzilla::Object::check_boolean }; @@ -155,99 +146,6 @@ sub update { $dbh->bz_start_transaction(); my ($changes, $old_self) = $self->SUPER::update(@_); - # We also have to fix votes. - my @msgs; # Will store emails to send to voters. - if ($changes->{maxvotesperbug} || $changes->{votesperuser} || $changes->{votestoconfirm}) { - # We cannot |use| these modules, due to dependency loops. - require Bugzilla::Bug; - import Bugzilla::Bug qw(RemoveVotes CheckIfVotedConfirmed); - require Bugzilla::User; - import Bugzilla::User qw(user_id_to_login); - - # 1. too many votes for a single user on a single bug. - my @toomanyvotes_list = (); - if ($self->max_votes_per_bug < $self->votes_per_user) { - my $votes = $dbh->selectall_arrayref( - 'SELECT votes.who, votes.bug_id - FROM votes - INNER JOIN bugs - ON bugs.bug_id = votes.bug_id - WHERE bugs.product_id = ? - AND votes.vote_count > ?', - undef, ($self->id, $self->max_votes_per_bug)); - - foreach my $vote (@$votes) { - my ($who, $id) = (@$vote); - # If some votes are removed, RemoveVotes() returns a list - # of messages to send to voters. - push(@msgs, RemoveVotes($id, $who, 'votes_too_many_per_bug')); - my $name = user_id_to_login($who); - - push(@toomanyvotes_list, {id => $id, name => $name}); - } - } - $changes->{'too_many_votes'} = \@toomanyvotes_list; - - # 2. too many total votes for a single user. - # This part doesn't work in the general case because RemoveVotes - # doesn't enforce votesperuser (except per-bug when it's less - # than maxvotesperbug). See Bugzilla::Bug::RemoveVotes(). - - my $votes = $dbh->selectall_arrayref( - 'SELECT votes.who, votes.vote_count - FROM votes - INNER JOIN bugs - ON bugs.bug_id = votes.bug_id - WHERE bugs.product_id = ?', - undef, $self->id); - - my %counts; - foreach my $vote (@$votes) { - my ($who, $count) = @$vote; - if (!defined $counts{$who}) { - $counts{$who} = $count; - } else { - $counts{$who} += $count; - } - } - my @toomanytotalvotes_list = (); - foreach my $who (keys(%counts)) { - if ($counts{$who} > $self->votes_per_user) { - my $bug_ids = $dbh->selectcol_arrayref( - 'SELECT votes.bug_id - FROM votes - INNER JOIN bugs - ON bugs.bug_id = votes.bug_id - WHERE bugs.product_id = ? - AND votes.who = ?', - undef, ($self->id, $who)); - - foreach my $bug_id (@$bug_ids) { - # RemoveVotes() returns a list of messages to send - # in case some voters had too many votes. - push(@msgs, RemoveVotes($bug_id, $who, 'votes_too_many_per_user')); - my $name = user_id_to_login($who); - - push(@toomanytotalvotes_list, {id => $bug_id, name => $name}); - } - } - } - $changes->{'too_many_total_votes'} = \@toomanytotalvotes_list; - - # 3. enough votes to confirm - my $bug_list = - $dbh->selectcol_arrayref('SELECT bug_id FROM bugs WHERE product_id = ? - AND bug_status = ? AND votes >= ?', - undef, ($self->id, 'UNCONFIRMED', $self->votes_to_confirm)); - - my @updated_bugs = (); - foreach my $bug_id (@$bug_list) { - my $confirmed = CheckIfVotedConfirmed($bug_id); - push (@updated_bugs, $bug_id) if $confirmed; - } - $changes->{'confirmed_bugs'} = \@updated_bugs; - } - # Also update group settings. if ($self->{check_group_controls}) { require Bugzilla::Bug; @@ -364,11 +262,6 @@ sub update { delete $self->{check_group_controls}; Bugzilla->user->clear_product_cache(); - # Now that changes have been committed, we can send emails to voters. - foreach my $msg (@msgs) { - MessageToMTA($msg); - } - return $changes; } @@ -524,37 +417,6 @@ sub _check_milestone_url { return $url; } -sub _check_votes_per_user { - return _check_votes(@_, 0); -} - -sub _check_votes_per_bug { - return _check_votes(@_, 10000); -} - -sub _check_votes_to_confirm { - return _check_votes(@_, 0); -} - -# This subroutine is only used internally by other _check_votes_* validators. -sub _check_votes { - my ($invocant, $votes, $field, $default) = @_; - - detaint_natural($votes); - # On product creation, if the number of votes is not a valid integer, - # we silently fall back to the given default value. - # If the product already exists and the change is illegal, we complain. - if (!defined $votes) { - if (ref $invocant) { - ThrowUserError('product_illegal_votes', {field => $field, votes => $_[1]}); - } - else { - $votes = $default; - } - } - return $votes; -} - ##################################### # Implement Bugzilla::Field::Choice # ##################################### @@ -618,9 +480,6 @@ sub set_name { $_[0]->set('name', $_[1]); } sub set_description { $_[0]->set('description', $_[1]); } sub set_default_milestone { $_[0]->set('defaultmilestone', $_[1]); } sub set_is_active { $_[0]->set('isactive', $_[1]); } -sub set_votes_per_user { $_[0]->set('votesperuser', $_[1]); } -sub set_votes_per_bug { $_[0]->set('maxvotesperbug', $_[1]); } -sub set_votes_to_confirm { $_[0]->set('votestoconfirm', $_[1]); } sub set_allows_unconfirmed { $_[0]->set('allows_unconfirmed', $_[1]); } sub set_group_controls { @@ -876,9 +735,6 @@ sub flag_types { sub allows_unconfirmed { return $_[0]->{'allows_unconfirmed'}; } sub description { return $_[0]->{'description'}; } sub is_active { return $_[0]->{'isactive'}; } -sub votes_per_user { return $_[0]->{'votesperuser'}; } -sub max_votes_per_bug { return $_[0]->{'maxvotesperbug'}; } -sub votes_to_confirm { return $_[0]->{'votestoconfirm'}; } sub default_milestone { return $_[0]->{'defaultmilestone'}; } sub classification_id { return $_[0]->{'classification_id'}; } @@ -939,9 +795,6 @@ Bugzilla::Product - Bugzilla product class. my $name = $product->name; my $description = $product->description; my isactive = $product->is_active; - my votesperuser = $product->votes_per_user; - my maxvotesperbug = $product->max_votes_per_bug; - my votestoconfirm = $product->votes_to_confirm; my $defaultmilestone = $product->default_milestone; my $classificationid = $product->classification_id; my $allows_unconfirmed = $product->allows_unconfirmed; diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index d85da01a4..52c99903d 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -86,10 +86,8 @@ use constant SPECIAL_ORDER_JOIN => { # 3. title: The title of the column as displayed to users. # # Note: There are a few hacks in the code that deviate from these definitions. -# In particular, when the list is sorted by the "votes" field the word -# "DESC" is added to the end of the field to sort in descending order, -# and the redundant short_desc column is removed when the client -# requests "all" columns. +# In particular, the redundant short_desc column is removed when the +# client requests "all" columns. # # This is really a constant--that is, once it's been called once, the value # will always be the same unless somebody adds a new custom field. But @@ -281,18 +279,6 @@ sub init { push(@supptables, "LEFT JOIN flagtypes ON flagtypes.id = flags.type_id"); } - my $minvotes; - if (defined $params->param('votes')) { - my $c = trim($params->param('votes')); - if ($c ne "") { - if ($c !~ /^[0-9]*$/) { - ThrowUserError("illegal_at_least_x_votes", - { value => $c }); - } - push(@specialchart, ["votes", "greaterthan", $c - 1]); - } - } - # If the user has selected all of either status or resolution, change to # selecting none. This is functionally equivalent, but quite a lot faster. # Also, if the status is __open__ or __closed__, translate those diff --git a/Bugzilla/Search/Quicksearch.pm b/Bugzilla/Search/Quicksearch.pm index 2f9e0734f..1e0bdc437 100644 --- a/Bugzilla/Search/Quicksearch.pm +++ b/Bugzilla/Search/Quicksearch.pm @@ -339,12 +339,6 @@ sub _handle_special_first_chars { sub _handle_field_names { my ($or_operand, $negate, $unknownFields, $ambiguous_fields) = @_; - # votes:xx ("at least xx votes") - if ($or_operand =~ /^votes:([0-9]+)$/) { - addChart('votes', 'greaterthan', $1 - 1, $negate); - return 1; - } - # Flag and requestee shortcut if ($or_operand =~ /^(?:flag:)?([^\?]+\?)([^\?]*)$/) { addChart('flagtypes.name', 'substring', $1, $negate); @@ -454,18 +448,6 @@ sub _special_field_syntax { return 1; } - # Votes (votes>xx) - if ($word =~ m/^votes>([0-9]+)$/) { - addChart('votes', 'greaterthan', $1, $negate); - return 1; - } - - # Votes (votes>=xx, votes=>xx) - if ($word =~ m/^votes(>=|=>)([0-9]+)$/) { - addChart('votes', 'greaterthan', $2-1, $negate); - return 1; - } - return 0; } diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm index 711a45f44..1d7b9f7d9 100644 --- a/Bugzilla/WebService/Bug.pm +++ b/Bugzilla/WebService/Bug.pm @@ -386,9 +386,6 @@ sub search { if (my $when = delete $params->{creation_ts}) { $params->{WHERE}->{'creation_ts >= ?'} = $when; } - if (my $votes = delete $params->{votes}) { - $params->{WHERE}->{'votes >= ?'} = $votes; - } if (my $summary = delete $params->{short_desc}) { my @strings = ref $summary ? @$summary : ($summary); my @likes = ("short_desc LIKE ?") x @strings; @@ -1687,11 +1684,6 @@ C The "URL" field of a bug. C The Version field of a bug. -=item C - -C Searches for bugs with this many votes or greater. May not -be an array. - =item C C Search the "Status Whiteboard" field on bugs for a substring. @@ -1722,6 +1714,8 @@ for that value. =item Added in Bugzilla B<3.4>. +=item Searching by C was removed in Bugzilla B<3.8>. + =back =back -- cgit v1.2.3-24-g4f1b