summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/DB/Schema.pm2
-rw-r--r--Bugzilla/User.pm99
2 files changed, 100 insertions, 1 deletions
diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm
index 2c8b4a284..0c976e33e 100644
--- a/Bugzilla/DB/Schema.pm
+++ b/Bugzilla/DB/Schema.pm
@@ -1311,7 +1311,7 @@ use constant ABSTRACT_SCHEMA => {
# group, given the ability to bless another group, or given
# visibility to another groups existence and membership
# grant_type:
- # if GROUP_MEMBERSHIP - member groups are made members of grantor
+ # if GROUP_MEMBERSHIP - member groups are made members of grantor
# if GROUP_BLESS - member groups may grant membership in grantor
# if GROUP_VISIBLE - member groups may see grantor group
group_group_map => {
diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm
index 3fe59fe76..ac7d5094f 100644
--- a/Bugzilla/User.pm
+++ b/Bugzilla/User.pm
@@ -1007,6 +1007,105 @@ sub groups {
return $self->{groups};
}
+sub force_bug_dissociation {
+ my ($self, $nobody, $groups, $timestamp) = @_;
+ my $dbh = Bugzilla->dbh;
+ my $auto_user = Bugzilla->user;
+ $timestamp //= $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
+
+ my $group_marks = join(", ", ('?') x @$groups);
+ my $user_id = $self->id;
+ my @params = ($user_id, $user_id, $user_id, $user_id,
+ map { blessed $_ ? $_->id : $_ } @$groups);
+ my $bugs = $dbh->selectall_arrayref(qq{
+ SELECT
+ bugs.bug_id,
+ bugs.reporter_accessible,
+ bugs.reporter = ? AS match_reporter,
+ bugs.assigned_to = ? AS match_assignee,
+ bugs.qa_contact = ? AS match_qa_contact,
+ cc.who = ? AS match_cc
+ FROM
+ bug_group_map
+ JOIN
+ bugs ON bug_group_map.bug_id = bugs.bug_id
+ LEFT JOIN
+ cc ON cc.bug_id = bugs.bug_id
+ WHERE
+ group_id IN ($group_marks)
+ HAVING match_reporter AND reporter_accessible
+ OR match_assignee
+ OR match_qa_contact
+ OR match_cc
+ }, { Slice => {} }, @params);
+
+ my @reporter_bugs = map { $_->{bug_id} } grep { $_->{match_reporter} } @$bugs;
+ my @assignee_bugs = map { $_->{bug_id} } grep { $_->{match_assignee} } @$bugs;
+ my @qa_bugs = map { $_->{bug_id} } grep { $_->{match_qa_contact} } @$bugs;
+ my @cc_bugs = map { $_->{bug_id} } grep { $_->{match_cc} } @$bugs;
+
+ # Reporter - set reporter_accessible to false
+ my $reporter_accessible_field_id = get_field_id('reporter_accessible');
+ foreach my $bug_id (@reporter_bugs) {
+ $dbh->do(
+ q{INSERT INTO bugs_activity (bug_id, who, bug_when, fieldid, removed, added)
+ VALUES (?, ?, ?, ?, ?, ?)},
+ undef, $bug_id, $auto_user->id, $timestamp, $reporter_accessible_field_id, 1, 0);
+ $dbh->do(
+ q{UPDATE bugs SET reporter_accessible = 0, delta_ts = ?, lastdiffed = ?
+ WHERE bug_id = ?},
+ undef, $timestamp, $timestamp, $bug_id);
+ }
+
+ # Assignee
+ my $assigned_to_field_id = get_field_id('assigned_to');
+ foreach my $bug_id (@assignee_bugs) {
+ $dbh->do(
+ q{INSERT INTO bugs_activity (bug_id, who, bug_when, fieldid, removed, added)
+ VALUES (?, ?, ?, ?, ?, ?)},
+ undef, $bug_id, $auto_user->id, $timestamp, $assigned_to_field_id,
+ $self->login, $auto_user->login);
+ $dbh->do(
+ q{UPDATE bugs SET assigned_to = ?, delta_ts = ?, lastdiffed = ?
+ WHERE bug_id = ?},
+ undef, $nobody->id, $timestamp, $timestamp, $bug_id);
+ }
+
+ # QA Contact
+ my $qa_field_id = get_field_id('qa_contact');
+ foreach my $bug_id (@qa_bugs) {
+ $dbh->do(
+ q{INSERT INTO bugs_activity (bug_id, who, bug_when, fieldid, removed, added)
+ VALUES (?, ?, ?, ?, ?, '')},
+ undef, $bug_id, $auto_user->id, $timestamp, $qa_field_id, $self->login);
+ $dbh->do(
+ q{UPDATE bugs SET qa_contact = NULL, delta_ts = ?, lastdiffed = ?
+ WHERE bug_id = ?},
+ undef, $timestamp, $timestamp, $bug_id);
+ }
+
+ # CC list
+ my $cc_field_id = get_field_id('cc');
+ foreach my $bug_id (@cc_bugs) {
+ $dbh->do(
+ q{INSERT INTO bugs_activity (bug_id, who, bug_when, fieldid, removed, added)
+ VALUES (?, ?, ?, ?, ?, '')},
+ undef, $bug_id, $auto_user->id, $timestamp, $cc_field_id, $self->login);
+ $dbh->do(q{DELETE FROM cc WHERE bug_id = ? AND who = ?},
+ undef, $bug_id, $self->id);
+ }
+
+ if (@reporter_bugs || @assignee_bugs || @qa_bugs || @cc_bugs) {
+ $self->clear_last_statistics_ts();
+
+ # It's complex to determine which items now need to be flushed from memcached.
+ # As this is expected to be a rare event, we just flush the entire cache.
+ Bugzilla->memcached->clear_all();
+ }
+
+ return $bugs;
+}
+
sub last_visited {
my ($self) = @_;