diff --git a/core/classes/BugFilterQuery.class.php b/core/classes/BugFilterQuery.class.php index 1e5cc02112..a90bc460ec 100644 --- a/core/classes/BugFilterQuery.class.php +++ b/core/classes/BugFilterQuery.class.php @@ -1053,26 +1053,70 @@ protected function build_prop_note_by() { * @return void */ protected function build_prop_relationship() { - $t_any_found = false; - $c_rel_type = $this->filter[FILTER_PROPERTY_RELATIONSHIP_TYPE]; - $c_rel_bug = $this->filter[FILTER_PROPERTY_RELATIONSHIP_BUG]; - if( -1 == $c_rel_type || 0 == $c_rel_bug ) { + $c_rel_type = (int)$this->filter[FILTER_PROPERTY_RELATIONSHIP_TYPE]; + $c_rel_bug = (int)$this->filter[FILTER_PROPERTY_RELATIONSHIP_BUG]; + if( BUG_REL_ANY == $c_rel_type && META_FILTER_ANY == $c_rel_bug ) { return; } # use the complementary type - $t_comp_type = relationship_get_complementary_type( $c_rel_type ); + if( $c_rel_type >= 0 ) { + $t_comp_type = relationship_get_complementary_type( $c_rel_type ); + } $t_table_dst = 'rel_dst'; $t_table_src = 'rel_src'; + + # build conditions for relation type and bug match + if( BUG_REL_NONE == $c_rel_type ) { + if( META_FILTER_NONE == $c_rel_bug + || META_FILTER_ANY == $c_rel_bug ) { + # rel NONE, bug ANY/NONE, those bugs that are not related in any way to another + $t_where = $t_table_dst . '.relationship_type IS NULL AND ' . $t_table_src . '.relationship_type IS NULL'; + } else { + # rel NONE, bug ID, those bugs that are not related in any way to bug ID + # map to a non-existant relation type -1 to include nulls + # not including the self id + $t_where = 'NOT COALESCE(' . $t_table_dst . '.source_bug_id, -1) = ' . $this->param( $c_rel_bug ) + . ' AND NOT COALESCE(' . $t_table_src . '.destination_bug_id, -1) = ' . $this->param( $c_rel_bug ) + . ' AND NOT {bug}.id = ' . $this->param( $c_rel_bug ); + } + } elseif( BUG_REL_ANY == $c_rel_type ) { + if( META_FILTER_NONE == $c_rel_bug ) { + # rel ANY, bug NONE, bugs that are not related in any way to another + $t_where = $t_table_dst . '.relationship_type IS NULL AND ' . $t_table_src . '.relationship_type IS NULL'; + } elseif ( META_FILTER_ANY == $c_rel_bug ) { + # rel ANY, bug ANY, do nothing + return; + } else { + # rel ANY, bug ID, those bugs that have any relation to bug ID + $t_where = '(' . $t_table_dst . '.source_bug_id = ' . $this->param( $c_rel_bug ) + . ' OR ' . $t_table_src . '.destination_bug_id = ' . $this->param( $c_rel_bug ) . ')'; + } + } else { + # relation is specified + if( META_FILTER_NONE == $c_rel_bug ) { + # rel REL, bug NONE, those bugs that dont have any REL relation (may have other types) + # map to a non-existant relation type -1 to include nulls + $t_where = 'COALESCE(' . $t_table_dst . '.relationship_type, -1) <> ' . $this->param( $t_comp_type ) + . ' AND COALESCE(' . $t_table_src . '.relationship_type, -1) <> ' . $this->param( $c_rel_type ); + } elseif( META_FILTER_ANY == $c_rel_bug ) { + # rel REL, bug ANY, those bugs that are related by REL to any bug + $t_where = '(' . $t_table_dst . '.relationship_type=' . $this->param( $t_comp_type ) + . ' OR ' . $t_table_src . '.relationship_type=' . $this->param( $c_rel_type ) . ')'; + } else { + # rel REL, bug ID, those bugs that are related by REL to bug ID + $t_where = '(' + . $t_table_dst . '.relationship_type=' . $this->param( $t_comp_type ) + . ' AND ' . $t_table_dst . '.source_bug_id=' . $this->param( $c_rel_bug ) + . ' OR ' + . $t_table_src . '.relationship_type=' . $this->param( $c_rel_type ) + . ' AND ' . $t_table_src . '.destination_bug_id=' . $this->param( $c_rel_bug ) + . ')'; + } + } + $this->add_join( 'LEFT JOIN {bug_relationship} ' . $t_table_dst . ' ON ' . $t_table_dst . '.destination_bug_id = {bug}.id' ); $this->add_join( 'LEFT JOIN {bug_relationship} ' . $t_table_src . ' ON ' . $t_table_src . '.source_bug_id = {bug}.id' ); - - # get reverse relationships - $t_clauses = array(); - $t_clauses[] = '(' . $t_table_dst . '.relationship_type=' . $this->param( $t_comp_type ) - . ' AND ' . $t_table_dst . '.source_bug_id=' . $this->param( $c_rel_bug ) . ')'; - $t_clauses[] = '(' . $t_table_src . '.relationship_type=' . $this->param( $c_rel_type ) - . ' AND ' . $t_table_src . '.destination_bug_id=' . $this->param( $c_rel_bug ) . ')'; - $this->add_where( '(' . implode( ' OR ', $t_clauses ) . ')' ); + $this->add_where( $t_where ); } /** diff --git a/core/filter_form_api.php b/core/filter_form_api.php index 6c7877ba9e..a48e73f512 100644 --- a/core/filter_form_api.php +++ b/core/filter_form_api.php @@ -1542,10 +1542,37 @@ function print_filter_values_relationship_type( array $p_filter ) { echo ''; $c_rel_type = $t_filter[FILTER_PROPERTY_RELATIONSHIP_TYPE]; $c_rel_bug = $t_filter[FILTER_PROPERTY_RELATIONSHIP_BUG]; - if( -1 == $c_rel_type || 0 == $c_rel_bug ) { - echo lang_get( 'any' ); + if( BUG_REL_ANY == $c_rel_type ) { + switch ( $c_rel_bug ) { + case META_FILTER_NONE: + echo lang_get( 'none' ); + case META_FILTER_ANY: + echo lang_get( 'any' ); + break; + default; + echo lang_get( 'any' ),' ' , lang_get( 'with' ), ' ', $c_rel_bug; + } + } elseif( BUG_REL_NONE == $c_rel_type ) { + echo lang_get( 'none' ); + switch ( $c_rel_bug ) { + case META_FILTER_NONE: + case META_FILTER_ANY: + break; + default; + echo ' ', lang_get( 'with' ), ' ', $c_rel_bug; + } } else { - echo relationship_get_description_for_history( $c_rel_type ) . ' ' . $c_rel_bug; + echo relationship_get_description_for_history( $c_rel_type ) . ' '; + switch ( $c_rel_bug ) { + case META_FILTER_NONE: + echo lang_get( 'none' ); + break; + case META_FILTER_ANY: + echo lang_get( 'any' ); + break; + default; + echo $c_rel_bug; + } } } @@ -1564,7 +1591,7 @@ function print_filter_relationship_type( array $p_filter = null ) { if( !$c_reltype_value ) { $c_reltype_value = -1; } - relationship_list_box( $c_reltype_value, 'relationship_type', true, false, "input-xs" ); + relationship_list_box( $c_reltype_value, 'relationship_type', true, true, "input-xs" ); echo ''; } diff --git a/lang/strings_english.txt b/lang/strings_english.txt index 78fcfc8ae7..8bef9f2490 100644 --- a/lang/strings_english.txt +++ b/lang/strings_english.txt @@ -1397,6 +1397,7 @@ $s_bug_created_from = 'Issue generated from'; $s_copy_from_parent = 'Copy extended data from parent issue'; $s_copy_notes_from_parent = 'Copy issue notes'; $s_copy_attachments_from_parent = 'Copy attachments'; +$s_with = 'with'; # Relationship Graphs $s_viewing_bug_relationship_graph_title = 'Relationship Graph';