diff options
Diffstat (limited to 'Bugzilla')
-rw-r--r-- | Bugzilla/DB/Schema.pm | 2 | ||||
-rw-r--r-- | Bugzilla/User.pm | 99 |
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) = @_; |