summaryrefslogtreecommitdiffstats
path: root/extensions/TrackingFlags
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/TrackingFlags')
-rw-r--r--extensions/TrackingFlags/Extension.pm62
-rw-r--r--extensions/TrackingFlags/bin/bulk_flag_clear.pl137
-rw-r--r--extensions/TrackingFlags/lib/Flag.pm4
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;
}