diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB.pm b/mozilla/webtools/bugzilla/Bugzilla/DB.pm
index 7e40c162789..830d2835e78 100644
--- a/mozilla/webtools/bugzilla/Bugzilla/DB.pm
+++ b/mozilla/webtools/bugzilla/Bugzilla/DB.pm
@@ -837,6 +837,14 @@ sub bz_drop_table {
}
}
+sub bz_fk_info {
+ my ($self, $table, $column) = @_;
+ my $col_info = $self->bz_column_info($table, $column);
+ return undef if !$col_info;
+ my $fk = $col_info->{REFERENCES};
+ return $fk;
+}
+
sub bz_rename_column {
my ($self, $table, $old_name, $new_name) = @_;
diff --git a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema.pm b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema.pm
index a1102dd6441..dbea63f79f8 100644
--- a/mozilla/webtools/bugzilla/Bugzilla/DB/Schema.pm
+++ b/mozilla/webtools/bugzilla/Bugzilla/DB/Schema.pm
@@ -610,10 +610,12 @@ use constant ABSTRACT_SCHEMA => {
DEFAULT => '0'},
grant_group_id => {TYPE => 'INT3',
REFERENCES => {TABLE => 'groups',
- COLUMN => 'id'}},
+ COLUMN => 'id',
+ DELETE => 'SET NULL'}},
request_group_id => {TYPE => 'INT3',
REFERENCES => {TABLE => 'groups',
- COLUMN => 'id'}},
+ COLUMN => 'id',
+ DELETE => 'SET NULL'}},
],
},
diff --git a/mozilla/webtools/bugzilla/Bugzilla/Group.pm b/mozilla/webtools/bugzilla/Bugzilla/Group.pm
index 2e8a975d253..c936593bc44 100644
--- a/mozilla/webtools/bugzilla/Bugzilla/Group.pm
+++ b/mozilla/webtools/bugzilla/Bugzilla/Group.pm
@@ -84,21 +84,49 @@ sub user_regexp { return $_[0]->{'userregexp'}; }
sub is_active { return $_[0]->{'isactive'}; }
sub icon_url { return $_[0]->{'icon_url'}; }
+sub bugs {
+ my $self = shift;
+ return $self->{bugs} if exists $self->{bugs};
+ my $bug_ids = Bugzilla->dbh->selectcol_arrayref(
+ 'SELECT bug_id FROM bug_group_map WHERE group_id = ?',
+ undef, $self->id);
+ require Bugzilla::Bug;
+ $self->{bugs} = Bugzilla::Bug->new_from_list($bug_ids);
+ return $self->{bugs};
+}
+
sub members_direct {
my ($self) = @_;
- return $self->{members_direct} if defined $self->{members_direct};
- my $dbh = Bugzilla->dbh;
- my $user_ids = $dbh->selectcol_arrayref(
- "SELECT user_group_map.user_id
- FROM user_group_map
- WHERE user_group_map.group_id = ?
- AND grant_type = " . GRANT_DIRECT . "
- AND isbless = 0", undef, $self->id);
- require Bugzilla::User;
- $self->{members_direct} = Bugzilla::User->new_from_list($user_ids);
+ $self->{members_direct} ||= $self->_get_members(GRANT_DIRECT);
return $self->{members_direct};
}
+sub members_non_inherited {
+ my ($self) = @_;
+ $self->{members_non_inherited} ||= $self->_get_members();
+ return $self->{members_non_inherited};
+}
+
+# A helper for members_direct and members_non_inherited
+sub _get_members {
+ my ($self, $grant_type) = @_;
+ my $dbh = Bugzilla->dbh;
+ my $grant_clause = $grant_type ? "AND grant_type = $grant_type" : "";
+ my $user_ids = $dbh->selectcol_arrayref(
+ "SELECT DISTINCT user_id
+ FROM user_group_map
+ WHERE isbless = 0 $grant_clause AND group_id = ?", undef, $self->id);
+ require Bugzilla::User;
+ return Bugzilla::User->new_from_list($user_ids);
+}
+
+sub flag_types {
+ my $self = shift;
+ require Bugzilla::FlagType;
+ $self->{flag_types} ||= Bugzilla::FlagType::match({ group => $self->id });
+ return $self->{flag_types};
+}
+
sub grant_direct {
my ($self, $type) = @_;
$self->{grant_direct} ||= {};
@@ -131,6 +159,30 @@ sub granted_by_direct {
return $self->{granted_by_direct}->{$type};
}
+sub products {
+ my $self = shift;
+ return $self->{products} if exists $self->{products};
+ my $product_data = Bugzilla->dbh->selectall_arrayref(
+ 'SELECT product_id, entry, membercontrol, othercontrol,
+ canedit, editcomponents, editbugs, canconfirm
+ FROM group_control_map WHERE group_id = ?', {Slice=>{}},
+ $self->id);
+ my @ids = map { $_->{product_id} } @$product_data;
+ require Bugzilla::Product;
+ my $products = Bugzilla::Product->new_from_list(\@ids);
+ my %data_map = map { $_->{product_id} => $_ } @$product_data;
+ my @retval;
+ foreach my $product (@$products) {
+ # Data doesn't need to contain product_id--we already have
+ # the product object.
+ delete $data_map{$product->id}->{product_id};
+ push(@retval, { controls => $data_map{$product->id},
+ product => $product });
+ }
+ $self->{products} = \@retval;
+ return $self->{products};
+}
+
###############################
#### Methods ####
###############################
@@ -165,6 +217,66 @@ sub update {
return $changes;
}
+sub check_remove {
+ my ($self, $params) = @_;
+
+ # System groups cannot be deleted!
+ if (!$self->is_bug_group) {
+ ThrowUserError("system_group_not_deletable", { name => $self->name });
+ }
+
+ # Groups having a special role cannot be deleted.
+ my @special_groups;
+ foreach my $special_group (GROUP_PARAMS) {
+ if ($self->name eq Bugzilla->params->{$special_group}) {
+ push(@special_groups, $special_group);
+ }
+ }
+ if (scalar(@special_groups)) {
+ ThrowUserError('group_has_special_role',
+ { name => $self->name,
+ groups => \@special_groups });
+ }
+
+ return if $params->{'test_only'};
+
+ my $cantdelete = 0;
+
+ my $users = $self->members_non_inherited;
+ if (scalar(@$users) && !$params->{'remove_from_users'}) {
+ $cantdelete = 1;
+ }
+
+ my $bugs = $self->bugs;
+ if (scalar(@$bugs) && !$params->{'remove_from_bugs'}) {
+ $cantdelete = 1;
+ }
+
+ my $products = $self->products;
+ if (scalar(@$products) && !$params->{'remove_from_products'}) {
+ $cantdelete = 1;
+ }
+
+ my $flag_types = $self->flag_types;
+ if (scalar(@$flag_types) && !$params->{'remove_from_flags'}) {
+ $cantdelete = 1;
+ }
+
+ ThrowUserError('group_cannot_delete', { group => $self }) if $cantdelete;
+}
+
+sub remove_from_db {
+ my $self = shift;
+ my $dbh = Bugzilla->dbh;
+ $self->check_remove(@_);
+ $dbh->do('DELETE FROM whine_schedules
+ WHERE mailto_type = ? AND mailto = ?',
+ undef, MAILTO_GROUP, $self->id);
+ # All the other tables will be handled by foreign keys when we
+ # drop the main "groups" row.
+ $self->SUPER::remove_from_db(@_);
+}
+
# Add missing entries in bug_group_map for bugs created while
# a mandatory group was disabled and which is now enabled again.
sub _enforce_mandatory {
@@ -224,20 +336,6 @@ sub _rederive_regexp {
}
}
-sub members_non_inherited {
- my ($self) = @_;
- return $self->{members_non_inherited}
- if exists $self->{members_non_inherited};
-
- my $member_ids = Bugzilla->dbh->selectcol_arrayref(
- 'SELECT DISTINCT user_id FROM user_group_map
- WHERE isbless = 0 AND group_id = ?',
- undef, $self->id) || [];
- require Bugzilla::User;
- $self->{members_non_inherited} = Bugzilla::User->new_from_list($member_ids);
- return $self->{members_non_inherited};
-}
-
sub flatten_group_membership {
my ($self, @groups) = @_;
@@ -414,6 +512,53 @@ be a member of this group.
=over
+=item CDescription
-
[% gid FILTER html %]
- [% name FILTER html %]
- [% description FILTER html_light %]
+ [% group.id FILTER html %]
+ [% group.name FILTER html %]
+ [% group.description FILTER html_light %]
One or more [% terms.bug %] reports are visible only to this group. - You cannot delete this group while any [% terms.bugs %] are using it. + [% IF group.bugs.size %] +
[% group.bugs.size FILTER html %] [%+ terms.bug %] reports are
+ visible only to this group. You cannot delete this group while any
+ [%+ terms.bugs %] are using it.
-
Show me
- which [% terms.bugs %] - Remove
- all [% terms.bugs %] from this group restriction for me.
NOTE: It's quite possible to make confidential [% terms.bugs %] public by checking this box. It is strongly suggested @@ -76,21 +77,63 @@ the box.
[% END %] - [% IF hasproduct %] -This group is tied to the [% name FILTER html %] product. - You cannot delete this group while it is tied to a product. + [% IF group.products.size %] +
This group is tied to the following products:
+ [% SET any_hidden = 0 %] +This group restricts who can make changes to flags of certain types.
You cannot delete this group while there are flag types using it.
-
Show
- me which types - Remove all
- flag types from this group for me.
Do you really want to delete this group?
- [% IF (hasusers || hasbugs || hasproduct || hasflags) %] + [% IF group.users.size || group.bugs.size || group.products.size + || group.flags.size + %]You must check all of the above boxes or correct the indicated problems first before you can proceed.
[% END %] @@ -123,7 +168,7 @@- +
diff --git a/mozilla/webtools/bugzilla/template/en/default/global/user-error.html.tmpl b/mozilla/webtools/bugzilla/template/en/default/global/user-error.html.tmpl index b40ff26b476..80172bb03ae 100644 --- a/mozilla/webtools/bugzilla/template/en/default/global/user-error.html.tmpl +++ b/mozilla/webtools/bugzilla/template/en/default/global/user-error.html.tmpl @@ -682,9 +682,10 @@ [% ELSIF error == "group_cannot_delete" %] [% title = "Cannot Delete Group" %] - The [% name FILTER html %] group cannot be deleted because + The [% group.name FILTER html %] group cannot be deleted because there are - records + records in the database which refer to it. All references to this group must be removed before you can remove it. @@ -1760,6 +1761,8 @@ flagtype [% ELSIF class == "Bugzilla::Field" %] field + [% ELSIF class == "Bugzilla::Group" %] + group [% ELSIF class == "Bugzilla::Product" %] product [% ELSIF class == "Bugzilla::Search::Saved" %]