summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Bug.pm
diff options
context:
space:
mode:
authorSimon Green <sgreen@redhat.com>2014-08-14 01:40:47 +0200
committerSimon Green <sgreen@redhat.com>2014-08-14 01:40:47 +0200
commit424b21e37cd9aeac01588ce0defd3ee665944b1d (patch)
tree594aa91a4fafc7c30d26e0ee9a160f62bf4d063f /Bugzilla/Bug.pm
parent6dbcec07eba4b0910c883141a85b0b9928b85f32 (diff)
downloadbugzilla-424b21e37cd9aeac01588ce0defd3ee665944b1d.tar.gz
bugzilla-424b21e37cd9aeac01588ce0defd3ee665944b1d.tar.xz
Bug 1012506 - Allow a bug to have multiple aliases
r=dkl, a=sgreen
Diffstat (limited to 'Bugzilla/Bug.pm')
-rw-r--r--Bugzilla/Bug.pm157
1 files changed, 122 insertions, 35 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index c4ddb943c..07266da9c 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -49,7 +49,7 @@ use parent qw(Bugzilla::Object Exporter);
use constant DB_TABLE => 'bugs';
use constant ID_FIELD => 'bug_id';
-use constant NAME_FIELD => 'alias';
+use constant NAME_FIELD => 'bug_id';
use constant LIST_ORDER => ID_FIELD;
# Bugs have their own auditing table, bugs_activity.
use constant AUDIT_CREATES => 0;
@@ -65,7 +65,6 @@ sub DB_COLUMNS {
my @custom_names = map {$_->name} @custom;
my @columns = (qw(
- alias
assigned_to
bug_file_loc
bug_id
@@ -208,7 +207,6 @@ sub UPDATE_COLUMNS {
Bugzilla->active_custom_fields;
my @custom_names = map {$_->name} @custom;
my @columns = qw(
- alias
assigned_to
bug_file_loc
bug_severity
@@ -318,7 +316,16 @@ sub new {
|| (ref($param) && $param->{id} =~ /\D/))
{
if ($param) {
- $param = { name => ref($param) ? $param->{id} : $param,
+ my $alias = ref($param) ? $param->{id} : $param;
+ my $bug_id = bug_alias_to_id($alias);
+ if (! $bug_id) {
+ my $error_self = {};
+ bless $error_self, $class;
+ $error_self->{'bug_id'} = $alias;
+ $error_self->{'error'} = 'InvalidBugId';
+ return $error_self;
+ }
+ $param = { id => $bug_id,
cache => ref($param) ? $param->{cache} : 0 };
}
else {
@@ -690,6 +697,7 @@ sub create {
# These are not a fields in the bugs table, so we don't pass them to
# insert_create_data.
+ my $bug_aliases = delete $params->{alias};
my $cc_ids = delete $params->{cc};
my $groups = delete $params->{groups};
my $depends_on = delete $params->{dependson};
@@ -788,6 +796,13 @@ sub create {
# but sometimes it's blank.
Bugzilla::Comment->insert_create_data($creation_comment);
+ # Set up aliases
+ my $sth_aliases = $dbh->prepare('INSERT INTO bugs_aliases (alias, bug_id) VALUES (?, ?)');
+ foreach my $alias (@$bug_aliases) {
+ trick_taint($alias);
+ $sth_aliases->execute($alias, $bug->bug_id);
+ }
+
Bugzilla::Hook::process('bug_end_of_create', { bug => $bug,
timestamp => $timestamp,
});
@@ -907,7 +922,26 @@ sub update {
my $added_names = join(', ', (map {$_->login} @$added_users));
$changes->{cc} = [$removed_names, $added_names];
}
-
+
+ # Aliases
+ my $old_aliases = $old_bug->alias;
+ my $new_aliases = $self->alias;
+ my ($removed_aliases, $added_aliases) = diff_arrays($old_aliases, $new_aliases);
+
+ foreach my $alias (@$removed_aliases) {
+ $dbh->do('DELETE FROM bugs_aliases WHERE bug_id = ? AND alias = ?',
+ undef, $self->id, $alias);
+ }
+ foreach my $alias (@$added_aliases) {
+ trick_taint($alias);
+ $dbh->do('INSERT INTO bugs_aliases (bug_id, alias) VALUES (?,?)',
+ undef, $self->id, $alias);
+ }
+ # If any changes were found, record it in the activity log
+ if (scalar @$removed_aliases || scalar @$added_aliases) {
+ $changes->{alias} = [join(', ', @$removed_aliases), join(', ', @$added_aliases)];
+ }
+
# Keywords
my @old_kw_ids = map { $_->id } @{$old_bug->keyword_objects};
my @new_kw_ids = map { $_->id } @{$self->keyword_objects};
@@ -1311,32 +1345,38 @@ sub _send_bugmail {
#####################################################################
sub _check_alias {
- my ($invocant, $alias) = @_;
- $alias = trim($alias);
- return undef if (!$alias);
-
- # Make sure the alias isn't too long.
- if (length($alias) > 20) {
- ThrowUserError("alias_too_long");
- }
- # Make sure the alias isn't just a number.
- if ($alias =~ /^\d+$/) {
- ThrowUserError("alias_is_numeric", { alias => $alias });
- }
- # Make sure the alias has no commas or spaces.
- if ($alias =~ /[, ]/) {
- ThrowUserError("alias_has_comma_or_space", { alias => $alias });
- }
- # Make sure the alias is unique, or that it's already our alias.
- my $other_bug = new Bugzilla::Bug($alias);
- if (!$other_bug->{error}
- && (!ref $invocant || $other_bug->id != $invocant->id))
- {
- ThrowUserError("alias_in_use", { alias => $alias,
- bug_id => $other_bug->id });
+ my ($invocant, $aliases) = @_;
+ $aliases = ref $aliases ? $aliases : [split(/[\s,]+/, $aliases)];
+
+ # Remove empty aliases
+ @$aliases = grep { $_ } @$aliases;
+
+ foreach my $alias (@$aliases) {
+ $alias = trim($alias);
+
+ # Make sure the alias isn't too long.
+ if (length($alias) > 40) {
+ ThrowUserError("alias_too_long");
+ }
+ # Make sure the alias isn't just a number.
+ if ($alias =~ /^\d+$/) {
+ ThrowUserError("alias_is_numeric", { alias => $alias });
+ }
+ # Make sure the alias has no commas or spaces.
+ if ($alias =~ /[, ]/) {
+ ThrowUserError("alias_has_comma_or_space", { alias => $alias });
+ }
+ # Make sure the alias is unique, or that it's already our alias.
+ my $other_bug = new Bugzilla::Bug($alias);
+ if (!$other_bug->{error}
+ && (!ref $invocant || $other_bug->id != $invocant->id))
+ {
+ ThrowUserError("alias_in_use", { alias => $alias,
+ bug_id => $other_bug->id });
+ }
}
- return $alias;
+ return $aliases;
}
sub _check_assigned_to {
@@ -2376,6 +2416,13 @@ sub set_all {
work_time => $params->{'work_time'} });
}
+ if (exists $params->{alias} && $params->{alias}{set}) {
+ $params->{alias} = {
+ add => $params->{alias}{set},
+ remove => $self->alias,
+ };
+ }
+
my %normal_set_all;
foreach my $name (keys %$params) {
# These are handled separately below.
@@ -2400,6 +2447,7 @@ sub set_all {
}
$self->_add_remove($params, 'cc');
+ $self->_add_remove($params, 'alias');
# Theoretically you could move a product without ever specifying
# a new assignee or qa_contact, or adding/removing any CCs. So,
@@ -2416,14 +2464,13 @@ sub _add_remove {
my ($self, $params, $name) = @_;
my @add = @{ $params->{$name}->{add} || [] };
my @remove = @{ $params->{$name}->{remove} || [] };
- $name =~ s/s$//;
+ $name =~ s/s$// if $name ne 'alias';
my $add_method = "add_$name";
my $remove_method = "remove_$name";
$self->$add_method($_) foreach @add;
$self->$remove_method($_) foreach @remove;
}
-sub set_alias { $_[0]->set('alias', $_[1]); }
sub set_assigned_to {
my ($self, $value) = @_;
$self->set('assigned_to', $value);
@@ -2840,6 +2887,21 @@ sub remove_cc {
@$cc_users = grep { $_->id != $user->id } @$cc_users;
}
+sub add_alias {
+ my ($self, $alias) = @_;
+ return if !$alias;
+ my $aliases = $self->_check_alias($alias);
+ $alias = $aliases->[0];
+ my $bug_aliases = $self->alias;
+ push(@$bug_aliases, $alias) if !grep($_ eq $alias, @$bug_aliases);
+}
+
+sub remove_alias {
+ my ($self, $alias) = @_;
+ my $bug_aliases = $self->alias;
+ @$bug_aliases = grep { $_ ne $alias } @$bug_aliases;
+}
+
# $bug->add_comment("comment", {isprivate => 1, work_time => 10.5,
# type => CMT_NORMAL, extra_data => $data});
sub add_comment {
@@ -3167,7 +3229,6 @@ sub tags {
# These are accessors that don't need to access the database.
# Keep them in alphabetical order.
-sub alias { return $_[0]->{alias} }
sub bug_file_loc { return $_[0]->{bug_file_loc} }
sub bug_id { return $_[0]->{bug_id} }
sub bug_severity { return $_[0]->{bug_severity} }
@@ -3277,6 +3338,24 @@ sub actual_time {
return $self->{'actual_time'};
}
+sub alias {
+ my ($self) = @_;
+ return $self->{'alias'} if exists $self->{'alias'};
+ return [] if $self->{'error'};
+
+ my $dbh = Bugzilla->dbh;
+ $self->{'alias'} = $dbh->selectcol_arrayref(
+ q{SELECT alias
+ FROM bugs_aliases
+ WHERE bug_id = ?
+ ORDER BY alias},
+ undef, $self->bug_id);
+
+ $self->{'alias'} = [] if !scalar(@{$self->{'alias'}});
+
+ return $self->{'alias'};
+}
+
sub any_flags_requesteeble {
my ($self) = @_;
return $self->{'any_flags_requesteeble'}
@@ -3868,7 +3947,7 @@ sub bug_alias_to_id {
my $dbh = Bugzilla->dbh;
trick_taint($alias);
return $dbh->selectrow_array(
- "SELECT bug_id FROM bugs WHERE alias = ?", undef, $alias);
+ "SELECT bug_id FROM bugs_aliases WHERE alias = ?", undef, $alias);
}
#####################################################################
@@ -4497,6 +4576,16 @@ __END__
Ensures the accessors for custom fields are always created.
+=item C<add_alias($alias)>
+
+Adds an alias to the internal respresentation of the bug. You will need to
+call L<update> to make the changes permanent.
+
+=item C<remove_alias($alias)>
+
+Removes an alias from the internal respresentation of the bug. You will need to
+call L<update> to make the changes permanent.
+
=item C<update_user_last_visit($user, $last_visit)>
Creates or updates a L<Bugzilla::BugUserLastVisit> for this bug and the supplied
@@ -4664,8 +4753,6 @@ $user, the timestamp given as $last_visit.
=item remove_group
-=item set_alias
-
=item set_dup_id
=item set_target_milestone