From 1a4a843db26f6c3c208fa5dfdca7933b7cb76db2 Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Thu, 31 Dec 2009 12:48:21 +0000 Subject: Bug 520318: Add remove_from_db to Bugzilla:Group and use it to delete groups in editgroups.cgi Patch by Max Kanat-Alexander r=dkl, a=LpSolit --- Bugzilla/Group.pm | 187 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 166 insertions(+), 21 deletions(-) (limited to 'Bugzilla/Group.pm') diff --git a/Bugzilla/Group.pm b/Bugzilla/Group.pm index 2e8a975d2..c936593bc 100644 --- a/Bugzilla/Group.pm +++ b/Bugzilla/Group.pm @@ -84,19 +84,47 @@ 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}; + $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 user_group_map.user_id + "SELECT DISTINCT user_id FROM user_group_map - WHERE user_group_map.group_id = ? - AND grant_type = " . GRANT_DIRECT . " - AND isbless = 0", undef, $self->id); + WHERE isbless = 0 $grant_clause AND group_id = ?", undef, $self->id); require Bugzilla::User; - $self->{members_direct} = Bugzilla::User->new_from_list($user_ids); - return $self->{members_direct}; + 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 { @@ -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 C + +=over + +=item B + +Determines whether it's OK to remove this group from the database, and +throws an error if it's not OK. + +=item B + +=over + +=item C + +C If you want to only check if the group can be deleted I, +under any circumstances, specify C to just do the most basic tests +(the other parameters will be ignored in this situation, as those tests won't +be run). + +=item C + +C True if it would be OK to remove all users who are in this group +from this group. + +=item C + +C True if it would be OK to remove all bugs that are in this group +from this group. + +=item C + +C True if it would be OK to stop all flagtypes that reference +this group from referencing this group (e.g., as their grantgroup or +requestgroup). + +=item C + +C True if it would be OK to remove this group from all group controls +on products. + +=back + +=item B (nothing) + +=back + =item C Returns an arrayref of L objects representing people who are -- cgit v1.2.3-24-g4f1b