summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
authorSimon Green <mail@simon.green>2016-09-15 10:44:54 +0200
committerSimon Green <mail@simon.green>2016-09-15 10:44:54 +0200
commita4601960dedb6012dd12e6a6fe47de7fc6af6965 (patch)
tree0f43e9ab94d883603a67f7f3b6a491c275a5befa /Bugzilla
parentc7b85d80debaba707e0b77633ebbd21575268770 (diff)
downloadbugzilla-a4601960dedb6012dd12e6a6fe47de7fc6af6965.tar.gz
bugzilla-a4601960dedb6012dd12e6a6fe47de7fc6af6965.tar.xz
Bug 65388 - Make it possible to query for open bugs with an inactive target milestone
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Search.pm94
1 files changed, 92 insertions, 2 deletions
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index b922f5845..b806ff8da 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -163,6 +163,8 @@ use constant OPERATORS => {
changedby => \&_changedby,
isempty => \&_isempty,
isnotempty => \&_isnotempty,
+ isactive => \&_isactive,
+ isnotactive => \&_isactive,
};
# Some operators are really just standard SQL operators, and are
@@ -191,6 +193,8 @@ use constant OPERATOR_REVERSE => {
greaterthaneq => 'lessthan',
isempty => 'isnotempty',
isnotempty => 'isempty',
+ isactive => 'isnotactive',
+ isnotactive => 'isactive',
# The following don't currently have reversals:
# casesubstring, anyexact, allwords, allwordssubstr
};
@@ -210,6 +214,8 @@ use constant NON_NUMERIC_OPERATORS => qw(
use constant NO_VALUE_OPERATORS => qw(
isempty
isnotempty
+ isactive
+ isnotactive
);
use constant MULTI_SELECT_OVERRIDE => {
@@ -936,6 +942,16 @@ sub _multi_select_fields {
return $self->{multi_select_fields};
}
+# Select custom fields have an active field, so we need to know these fields
+# too. The type is important as we handle them differently.
+sub _select_fields {
+ my ($self) = @_;
+ $self->{select_fields} ||= Bugzilla->fields({
+ by_name => 1,
+ type => [FIELD_TYPE_MULTI_SELECT, FIELD_TYPE_SINGLE_SELECT]});
+ return $self->{select_fields};
+}
+
# $self->{params} contains values that could be undef, could be a string,
# or could be an arrayref. Sometimes we want that value as an array,
# always.
@@ -2478,7 +2494,7 @@ sub _user_nonchanged {
# For negative operators, the system we're using here
# only works properly if we reverse the operator and check IS NULL
# in the WHERE.
- my $is_negative = $operator =~ /^(?:no|isempty)/ ? 1 : 0;
+ my $is_negative = $operator ne 'notactive' && $operator =~ /^(?:no|isempty)/ ? 1 : 0;
if ($is_negative) {
$args->{operator} = $self->_reverse_operator($operator);
}
@@ -2613,6 +2629,10 @@ sub _long_desc_nonchanged {
$args->{term} = $self->_multiselect_isempty($args, $operator eq 'isnotempty');
return;
}
+ if ($operator =~ /^is(not)?active$/) {
+ # Comments can't be (in)active
+ $self->_invalid_combination($args);
+ }
my $dbh = Bugzilla->dbh;
my $table = "longdescs_$chart_id";
@@ -2948,7 +2968,7 @@ sub _flagtypes_nonchanged {
# If you search for "Flags" (does not contain) "approval+" we actually want
# to return *bugs* that don't contain an approval+ flag. Without rewriting
# the negation we'll search for *flags* which don't contain approval+.
- if ($operator =~ s/^not//) {
+ if ($operator ne 'notactive' && $operator =~ s/^not//) {
$args->{operator} = $operator;
$condition->operator($operator);
$condition->negate(1);
@@ -3441,6 +3461,76 @@ sub _empty_value {
return "''";
}
+sub _isactive {
+ my ($self, $args) = @_;
+ my ($field, $chart_id, $operator, $joins, $bugs_table) =
+ @$args{qw(field chart_id operator joins bugs_table)};
+
+ my $value = $operator eq 'isnotactive' ? 0 : 1;
+
+ my @simple_fields = qw(bug_severity bug_status op_sys priority rep_platform
+ resolution version
+ );
+ my @user_fields = qw(attachments.submitter assigned_to assigned_to_realname
+ cc commenter reporter reporter_realname requestees.login_name
+ setters.login_name qa_contact qa_contact_realname
+ );
+
+ if ($field eq 'product' or $field eq 'component') {
+ $args->{term} = "${field}s.isactive = $value";
+ }
+ elsif (grep {$_ eq $field} @simple_fields) {
+ push @$joins, {
+ table => ($field eq 'version' ? 'versions' : $field),
+ as => "${field}_$chart_id",
+ from => $field,
+ to => 'value',
+ };
+ $args->{term} = "${field}_$chart_id.isactive = $value";
+ }
+ elsif ($field eq 'flagtypes.name') {
+ $args->{term} = "flagtypes_$chart_id.is_active = $value";
+ }
+ elsif ($field eq 'bug_group') {
+ $args->{term} = "groups.isactive = $value";
+ }
+ elsif ($field eq 'keywords') {
+ $args->{term} = "keyworddefs.is_active = $value";
+ }
+ elsif ($field eq 'target_milestone') {
+ push @$joins, {
+ table => 'milestones',
+ as => "milestones_$chart_id",
+ from => 'target_milestone',
+ to => 'value',
+ };
+ $args->{term} = qq{
+ (milestones_$chart_id.product_id = bugs.product_id AND
+ milestones_$chart_id.isactive = $value)
+ };
+ }
+ elsif (grep {$_ eq $field} @user_fields) {
+ my $as = "name_${field}_$chart_id";
+ # For fields with periods in their name.
+ $as =~ s/\./_/;
+ $args->{full_field} = "$as.disabled_text";
+ my $op = $value ? '=' : '!=';
+ $args->{term} = "$as.disabledtext $op ''";
+ }
+
+ elsif (my $field_obj = $self->_select_fields->{$field}) {
+ my $field_type = $field_obj->type;
+ $args->{term} = $field_type == FIELD_TYPE_MULTI_SELECT
+ ? 'value'
+ : "bugs.$field";
+ $args->{term} .= " IN (SELECT value FROM $field WHERE $field.isactive = $value)";
+ }
+ else {
+ # This field does not have an active value
+ $self->_invalid_combination($args);
+ }
+}
+
######################
# Public Subroutines #
######################