diff options
Diffstat (limited to 'extensions/TrackingFlags')
-rw-r--r-- | extensions/TrackingFlags/Extension.pm | 62 | ||||
-rw-r--r-- | extensions/TrackingFlags/bin/bulk_flag_clear.pl | 137 | ||||
-rw-r--r-- | extensions/TrackingFlags/lib/Flag.pm | 4 |
3 files changed, 181 insertions, 22 deletions
diff --git a/extensions/TrackingFlags/Extension.pm b/extensions/TrackingFlags/Extension.pm index 0432e7d2f..5a7e846ad 100644 --- a/extensions/TrackingFlags/Extension.pm +++ b/extensions/TrackingFlags/Extension.pm @@ -17,12 +17,13 @@ use Bugzilla::Extension::TrackingFlags::Flag::Bug; use Bugzilla::Extension::TrackingFlags::Admin; use Bugzilla::Bug; -use Bugzilla::Constants; -use Bugzilla::Field; -use Bugzilla::Product; use Bugzilla::Component; +use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::Extension::BMO::Data; +use Bugzilla::Field; +use Bugzilla::Install::Filesystem; +use Bugzilla::Product; our $VERSION = '1'; @@ -296,6 +297,15 @@ sub install_update_db { ); } +sub install_filesystem { + my ($self, $args) = @_; + my $files = $args->{files}; + my $extensions_dir = bz_locations()->{extensionsdir}; + $files->{"$extensions_dir/TrackingFlags/bin/bulk_flag_clear.pl"} = { + perms => Bugzilla::Install::Filesystem::OWNER_EXECUTE + }; +} + sub active_custom_fields { my ($self, $args) = @_; my $fields = $args->{'fields'}; @@ -362,24 +372,31 @@ sub bug_create_cf_accessors { my @tracking_flags = Bugzilla::Extension::TrackingFlags::Flag->get_all; foreach my $flag (@tracking_flags) { my $flag_name = $flag->name; - my $accessor = sub { - my $self = shift; - return $self->{$flag_name} if defined $self->{$flag_name}; - if (!exists $self->{'_tf_bug_values_preloaded'}) { - # preload all values currently set for this bug - my $bug_values - = Bugzilla::Extension::TrackingFlags::Flag::Bug->match({ bug_id => $self->id }); - foreach my $value (@$bug_values) { - $self->{$value->tracking_flag->name} = $value->value; - } - $self->{'_tf_bug_values_preloaded'} = 1; - } - return $self->{$flag_name} ||= '---'; - }; - my $name = "Bugzilla::Bug::$flag_name"; if (!Bugzilla::Bug->can($flag_name)) { + my $accessor = sub { + my $self = shift; + return $self->{$flag_name} if defined $self->{$flag_name}; + if (!exists $self->{'_tf_bug_values_preloaded'}) { + # preload all values currently set for this bug + my $bug_values + = Bugzilla::Extension::TrackingFlags::Flag::Bug->match({ bug_id => $self->id }); + foreach my $value (@$bug_values) { + $self->{$value->tracking_flag->name} = $value->value; + } + $self->{'_tf_bug_values_preloaded'} = 1; + } + return $self->{$flag_name} ||= '---'; + }; + no strict 'refs'; + *{"Bugzilla::Bug::$flag_name"} = $accessor; + } + if (!Bugzilla::Bug->can("set_$flag_name")) { + my $setter = sub { + my ($self, $value) = @_; + $self->set($flag_name, $value); + }; no strict 'refs'; - *{$name} = $accessor; + *{"Bugzilla::Bug::set_$flag_name"} = $setter; } } } @@ -466,7 +483,7 @@ sub bug_end_of_create { sub object_end_of_set_all { my ($self, $args) = @_; my $object = $args->{object}; - my $params = Bugzilla->input_params; + my $params = $args->{params}; return unless $object->isa('Bugzilla::Bug'); @@ -479,7 +496,10 @@ sub object_end_of_set_all { foreach my $flag (@$tracking_flags) { my $flag_name = $flag->name; if (exists $params->{$flag_name}) { - $object->set($flag_name, $params->{$flag_name}); + my $value = ref($params->{$flag_name}) + ? $params->{$flag_name}->[0] + : $params->{$flag_name}; + $object->set($flag_name, $value); } } } diff --git a/extensions/TrackingFlags/bin/bulk_flag_clear.pl b/extensions/TrackingFlags/bin/bulk_flag_clear.pl new file mode 100644 index 000000000..1eff355fe --- /dev/null +++ b/extensions/TrackingFlags/bin/bulk_flag_clear.pl @@ -0,0 +1,137 @@ +#!/usr/bin/perl -w +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +use strict; +use warnings; + +use FindBin '$RealBin'; +use lib "$RealBin/../../.."; +use lib "$RealBin/../../../lib"; +use lib "$RealBin/../lib"; + +BEGIN { + use Bugzilla; + Bugzilla->extensions; +} + +use Bugzilla::Constants; +use Bugzilla::Extension::TrackingFlags::Flag; +use Bugzilla::Extension::TrackingFlags::Flag::Bug; +use Bugzilla::User; + +use Getopt::Long; + +Bugzilla->usage_mode(USAGE_MODE_CMDLINE); + +my $config = {}; +GetOptions( + $config, + "trace=i", + "update_db", + "flag=s", + "modified_before=s", + "modified_after=s", + "value=s" +) or exit; +unless ($config->{flag} + && ($config->{modified_before} + || $config->{modified_after} + || $config->{value})) +{ + die <<EOF; +$0 + clears tracking flags matching the specified criteria. + the last-modified will be updated, however bugmail will not be generated. + +SYNTAX + $0 --flag <flag> (conditions) [--update_db] + +CONDITIONS + --modified_before <datetime> bug last-modified before <datetime> + --modified_after <datetime> bug last-modified after <datetime> + --value <flag value> flag = <flag value> + +OPTIONS + --update_db : by default only the impacted bugs will be listed. pass this + switch to update the database. +EOF +} + +# build sql + +my (@where, @values); + +my $flag = Bugzilla::Extension::TrackingFlags::Flag->check({ name => $config->{flag} }); +push @where, 'tracking_flags_bugs.tracking_flag_id = ?'; +push @values, $flag->flag_id; + +if ($config->{modified_before}) { + push @where, 'bugs.delta_ts < ?'; + push @values, $config->{modified_before}; +} + +if ($config->{modified_after}) { + push @where, 'bugs.delta_ts > ?'; + push @values, $config->{modified_after}; +} + +if ($config->{value}) { + push @where, 'tracking_flags_bugs.value = ?'; + push @values, $config->{value}; +} + +my $sql = " + SELECT tracking_flags_bugs.bug_id + FROM tracking_flags_bugs + INNER JOIN bugs ON bugs.bug_id = tracking_flags_bugs.bug_id + WHERE (" . join(") AND (", @where) . ") + ORDER BY tracking_flags_bugs.bug_id +"; + +# execute query + +my $dbh = Bugzilla->dbh; +$dbh->{TraceLevel} = $config->{trace} if $config->{trace}; + +my $bug_ids = $dbh->selectcol_arrayref($sql, undef, @values); + +if (!@$bug_ids) { + die "no matching bugs found\n"; +} + +if (!$config->{update_db}) { + print "bugs found: ", scalar(@$bug_ids), "\n\n", join(',', @$bug_ids), "\n\n"; + print "--update_db not provided, no changes made to the database\n"; + exit; +} + +# update bugs + +my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' }); +# put our nobody user into all groups to avoid permissions issues +$nobody->{groups} = [Bugzilla::Group->get_all]; +Bugzilla->set_user($nobody); + +foreach my $bug_id (@$bug_ids) { + print "updating bug $bug_id\n"; + $dbh->bz_start_transaction; + + # update the bug + # this will deal with history for us but not send bugmail + my $bug = Bugzilla::Bug->check({ id => $bug_id }); + $bug->set_all({ $flag->name => '---' }); + $bug->update; + + # update lastdiffed to skip bugmail for this change + $dbh->do( + "UPDATE bugs SET lastdiffed = delta_ts WHERE bug_id = ?", + undef, + $bug->id + ); + $dbh->bz_commit_transaction; +} diff --git a/extensions/TrackingFlags/lib/Flag.pm b/extensions/TrackingFlags/lib/Flag.pm index bc422243e..3ae7a937e 100644 --- a/extensions/TrackingFlags/lib/Flag.pm +++ b/extensions/TrackingFlags/lib/Flag.pm @@ -389,7 +389,9 @@ sub can_set_value { last; } } - return $new_value_obj && $user->in_group($new_value_obj->setter_group->name) + return $new_value_obj + && $new_value_obj->setter_group + && $user->in_group($new_value_obj->setter_group->name) ? 1 : 0; } |