summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Bug.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Bug.pm')
-rw-r--r--Bugzilla/Bug.pm47
1 files changed, 46 insertions, 1 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index fd28b5b82..1e418aa18 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -25,6 +25,7 @@
# Max Kanat-Alexander <mkanat@bugzilla.org>
# Frédéric Buclin <LpSolit@gmail.com>
# Lance Larsh <lance.larsh@oracle.com>
+# Elliotte Martin <elliotte_martin@yahoo.com>
package Bugzilla::Bug;
@@ -1761,7 +1762,42 @@ sub _check_select_field {
sub _check_bugid_field {
my ($invocant, $value, $field) = @_;
return undef if !$value;
- return $invocant->check($value, $field)->id;
+
+ # check that the value is a valid, visible bug id
+ my $checked_id = $invocant->check($value, $field)->id;
+
+ # check for loop (can't have a loop if this is a new bug)
+ if (ref $invocant) {
+ _check_relationship_loop($field, $invocant->bug_id, $checked_id);
+ }
+
+ return $checked_id;
+}
+
+sub _check_relationship_loop {
+ # Generates a dependency tree for a given bug. Calls itself recursively
+ # to generate sub-trees for the bug's dependencies.
+ my ($field, $bug_id, $dep_id, $ids) = @_;
+
+ # Don't do anything if this bug doesn't have any dependencies.
+ return unless defined($dep_id);
+
+ # Check whether we have seen this bug yet
+ $ids = {} unless defined $ids;
+ $ids->{$bug_id} = 1;
+ if ($ids->{$dep_id}) {
+ ThrowUserError("relationship_loop_single", {
+ 'bug_id' => $bug_id,
+ 'dep_id' => $dep_id,
+ 'field_name' => $field});
+ }
+
+ # Get this dependency's record from the database
+ my $dbh = Bugzilla->dbh;
+ my $next_dep_id = $dbh->selectrow_array(
+ "SELECT $field FROM bugs WHERE bug_id = ?", undef, $dep_id);
+
+ _check_relationship_loop($field, $dep_id, $next_dep_id, $ids);
}
#####################################################################
@@ -2553,6 +2589,15 @@ sub blocked {
# Even bugs in an error state always have a bug_id.
sub bug_id { $_[0]->{'bug_id'}; }
+sub related_bugs {
+ my ($self, $relationship) = @_;
+ return [] if $self->{'error'};
+
+ my $field_name = $relationship->name;
+ $self->{'related_bugs'}->{$field_name} ||= $self->match({$field_name => $self->id});
+ return $self->{'related_bugs'}->{$field_name};
+}
+
sub cc {
my ($self) = @_;
return $self->{'cc'} if exists $self->{'cc'};