summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/Search.pm125
-rwxr-xr-xbuglist.cgi2
-rw-r--r--skins/standard/buglist.css10
-rw-r--r--template/en/default/global/field-descs.none.tmpl28
-rw-r--r--template/en/default/list/list.html.tmpl27
-rw-r--r--template/en/default/search/boolean-charts.html.tmpl58
-rw-r--r--template/en/default/search/form.html.tmpl62
-rw-r--r--template/en/default/search/type-select.html.tmpl29
8 files changed, 229 insertions, 112 deletions
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index 557af6646..c1593ccc4 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -88,10 +88,6 @@ sub init {
@inputorder = @$orderref if $orderref;
my @orderby;
- my $debug = 0;
- my @debugdata;
- if ($params->param('debug')) { $debug = 1; }
-
my @fields;
my @supptables;
my @wherepart;
@@ -306,8 +302,22 @@ sub init {
my $sql_chvalue = $chvalue ne '' ? $dbh->quote($chvalue) : '';
trick_taint($sql_chvalue);
if(!@chfield) {
- push(@wherepart, "bugs.delta_ts >= $sql_chfrom") if ($sql_chfrom);
- push(@wherepart, "bugs.delta_ts <= $sql_chto") if ($sql_chto);
+ if ($sql_chfrom) {
+ my $term = "bugs.delta_ts >= $sql_chfrom";
+ push(@wherepart, $term);
+ $self->search_description({
+ field => 'delta_ts', type => 'greaterthaneq',
+ value => $chfieldfrom, term => $term,
+ });
+ }
+ if ($sql_chto) {
+ my $term = "bugs.delta_ts <= $sql_chto";
+ push(@wherepart, $term);
+ $self->search_description({
+ field => 'delta_ts', type => 'lessthaneq',
+ value => $chfieldto, term => $term,
+ });
+ }
} else {
my $bug_creation_clause;
my @list;
@@ -317,8 +327,22 @@ sub init {
# Treat [Bug creation] differently because we need to look
# at bugs.creation_ts rather than the bugs_activity table.
my @l;
- push(@l, "bugs.creation_ts >= $sql_chfrom") if($sql_chfrom);
- push(@l, "bugs.creation_ts <= $sql_chto") if($sql_chto);
+ if ($sql_chfrom) {
+ my $term = "bugs.creation_ts >= $sql_chfrom";
+ push(@l, $term);
+ $self->search_description({
+ field => 'creation_ts', type => 'greaterthaneq',
+ value => $chfieldfrom, term => $term,
+ });
+ }
+ if ($sql_chto) {
+ my $term = "bugs.creation_ts <= $sql_chto";
+ push(@l, $term);
+ $self->search_description({
+ field => 'creation_ts', type => 'lessthaneq',
+ value => $chfieldto, term => $term,
+ });
+ }
$bug_creation_clause = "(" . join(' AND ', @l) . ")";
} else {
push(@actlist, get_field_id($f));
@@ -330,18 +354,39 @@ sub init {
if(@actlist) {
my $extra = " actcheck.bug_id = bugs.bug_id";
push(@list, "(actcheck.bug_when IS NOT NULL)");
- if($sql_chfrom) {
- $extra .= " AND actcheck.bug_when >= $sql_chfrom";
- }
- if($sql_chto) {
- $extra .= " AND actcheck.bug_when <= $sql_chto";
- }
- if($sql_chvalue) {
- $extra .= " AND actcheck.added = $sql_chvalue";
- }
+
+ my $from_term = " AND actcheck.bug_when >= $sql_chfrom";
+ $extra .= $from_term if $sql_chfrom;
+ my $to_term = " AND actcheck.bug_when <= $sql_chto";
+ $extra .= $to_term if $sql_chto;
+ my $value_term = " AND actcheck.added = $sql_chvalue";
+ $extra .= $value_term if $sql_chvalue;
+
push(@supptables, "LEFT JOIN bugs_activity AS actcheck " .
"ON $extra AND "
. $dbh->sql_in('actcheck.fieldid', \@actlist));
+
+ foreach my $field (@chfield) {
+ next if $field eq "[Bug creation]";
+ if ($sql_chvalue) {
+ $self->search_description({
+ field => $field, type => 'changedto',
+ value => $chvalue, term => $value_term,
+ });
+ }
+ if ($sql_chfrom) {
+ $self->search_description({
+ field => $field, type => 'changedafter',
+ value => $chfieldfrom, term => $from_term,
+ });
+ }
+ if ($sql_chvalue) {
+ $self->search_description({
+ field => $field, type => 'changedbefore',
+ value => $chfieldto, term => $to_term,
+ });
+ }
+ }
}
# Now that we're done using @list to determine if there are any
@@ -367,7 +412,12 @@ sub init {
format => 'YYYY-MM-DD'});
$sql_deadlinefrom = $dbh->quote($deadlinefrom);
trick_taint($sql_deadlinefrom);
- push(@wherepart, "bugs.deadline >= $sql_deadlinefrom");
+ my $term = "bugs.deadline >= $sql_deadlinefrom";
+ push(@wherepart, $term);
+ $self->search_description({
+ field => 'deadline', type => 'greaterthaneq',
+ value => $deadlinefrom, term => $term,
+ });
}
if ($params->param('deadlineto')){
@@ -377,11 +427,16 @@ sub init {
format => 'YYYY-MM-DD'});
$sql_deadlineto = $dbh->quote($deadlineto);
trick_taint($sql_deadlineto);
- push(@wherepart, "bugs.deadline <= $sql_deadlineto");
+ my $term = "bugs.deadline <= $sql_deadlineto";
+ push(@wherepart, $term);
+ $self->search_description({
+ field => 'deadline', type => 'lessthaneq',
+ value => $deadlineto, term => $term,
+ });
}
}
- foreach my $f ("short_desc", "long_desc", "bug_file_loc",
+ foreach my $f ("short_desc", "longdesc", "bug_file_loc",
"status_whiteboard") {
if (defined $params->param($f)) {
my $s = trim($params->param($f));
@@ -447,6 +502,7 @@ sub init {
"^(?:deadline|creation_ts|delta_ts),(?:lessthan|greaterthan|equals|notequals),(?:-|\\+)?(?:\\d+)(?:[dDwWmMyY])\$" => \&_timestamp_compare,
"^commenter,(?:equals|anyexact),(%\\w+%)" => \&_commenter_exact,
"^commenter," => \&_commenter,
+ # The _ is allowed for backwards-compatibility with 3.2 and lower.
"^long_?desc," => \&_long_desc,
"^longdescs\.isprivate," => \&_longdescs_isprivate,
"^work_time,changedby" => \&_work_time_changedby,
@@ -526,12 +582,6 @@ sub init {
$params->param("field$chart-$row-$col", shift(@$ref));
$params->param("type$chart-$row-$col", shift(@$ref));
$params->param("value$chart-$row-$col", shift(@$ref));
- if ($debug) {
- push(@debugdata, "$row-$col = " .
- $params->param("field$chart-$row-$col") . ' | ' .
- $params->param("type$chart-$row-$col") . ' | ' .
- $params->param("value$chart-$row-$col") . ' *');
- }
$col++;
}
@@ -639,6 +689,7 @@ sub init {
$params->param("field$chart-$row-$col") ;
$col++) {
$f = $params->param("field$chart-$row-$col") || "noop";
+ my $original_f = $f; # Saved for search_description
$t = $params->param("type$chart-$row-$col") || "noop";
$v = $params->param("value$chart-$row-$col");
$v = "" if !defined $v;
@@ -665,24 +716,21 @@ sub init {
foreach my $key (@funcnames) {
if ("$f,$t,$rhs" =~ m/$key/) {
my $ref = $funcsbykey{$key};
- if ($debug) {
- push(@debugdata, "$key ($f / $t / $rhs) =>");
- }
$ff = $f;
if ($f !~ /\./) {
$ff = "bugs.$f";
}
$self->$ref(%func_args);
- if ($debug) {
- push(@debugdata, "$f / $t / $v / " .
- ($term || "undef") . " *");
- }
if ($term) {
last;
}
}
}
if ($term) {
+ $self->search_description({
+ field => $original_f, type => $t, value => $v,
+ term => $term,
+ });
push(@orlist, $term);
}
else {
@@ -808,7 +856,6 @@ sub init {
}
$self->{'sql'} = $query;
- $self->{'debugdata'} = \@debugdata;
}
###############################################################################
@@ -911,9 +958,13 @@ sub getSQL {
return $self->{'sql'};
}
-sub getDebugData {
- my $self = shift;
- return $self->{'debugdata'};
+sub search_description {
+ my ($self, $params) = @_;
+ my $desc = $self->{'search_description'} ||= [];
+ if ($params) {
+ push(@$desc, $params);
+ }
+ return $self->{'search_description'};
}
sub pronoun {
diff --git a/buglist.cgi b/buglist.cgi
index f83f957fc..037edae70 100755
--- a/buglist.cgi
+++ b/buglist.cgi
@@ -992,6 +992,7 @@ my $search = new Bugzilla::Search('fields' => \@selectnames,
'params' => $params,
'order' => \@orderstrings);
my $query = $search->getSQL();
+$vars->{'search_description'} = $search->search_description;
if (defined $cgi->param('limit')) {
my $limit = $cgi->param('limit');
@@ -1019,7 +1020,6 @@ if ($cgi->param('debug')) {
if (Bugzilla->user->in_group('admin')) {
$vars->{'query_explain'} = $dbh->bz_explain($query);
}
- $vars->{'debugdata'} = $search->getDebugData();
}
# Time to use server push to display an interim message to the user until
diff --git a/skins/standard/buglist.css b/skins/standard/buglist.css
index ca37dc763..fa50bcb2d 100644
--- a/skins/standard/buglist.css
+++ b/skins/standard/buglist.css
@@ -18,6 +18,16 @@
* Contributor(s): Myk Melez <myk@mozilla.org>
*/
+.search_description {
+ margin: .5em 0;
+ padding: 0;
+}
+.search_description li {
+ list-style-type: none;
+ display: inline;
+ margin-right: 2em;
+}
+
.bz_id_column {
}
diff --git a/template/en/default/global/field-descs.none.tmpl b/template/en/default/global/field-descs.none.tmpl
index 7d89bd5c2..324edb592 100644
--- a/template/en/default/global/field-descs.none.tmpl
+++ b/template/en/default/global/field-descs.none.tmpl
@@ -99,6 +99,34 @@
[% END %]
[% END %]
+[% SET search_descs = {
+ "noop" => "---",
+ "equals" => "is equal to",
+ "notequals" => "is not equal to",
+ "anyexact" => "is equal to any of the strings",
+ "substring" => "contains the string",
+ "casesubstring" => "contains the string (exact case)",
+ "notsubstring" => "does not contain the string",
+ "anywordssubstr" => "contains any of the strings",
+ "allwordssubstr" => "contains all of the strings",
+ "nowordssubstr" => "contains none of the strings",
+ "regexp" => "matches regular expression",
+ "notregexp" => "does not match regular expression",
+ "lessthan" => "is less than",
+ "lessthaneq" => "is less than or equal to",
+ "greaterthan" => "is greater than",
+ "greaterthaneq" => "is greater than or equal to",
+ "anywords" => "contains any of the words",
+ "allwords" => "contains all of the words",
+ "nowords" => "contains none of the words",
+ "changedbefore" => "changed before",
+ "changedafter" => "changed after",
+ "changedfrom" => "changed from",
+ "changedto" => "changed to",
+ "changedby" => "changed by",
+ "matches" => "matches",
+} %]
+
[% field_types = { ${constants.FIELD_TYPE_UNKNOWN} => "Unknown Type",
${constants.FIELD_TYPE_FREETEXT} => "Free Text",
${constants.FIELD_TYPE_SINGLE_SELECT} => "Drop Down",
diff --git a/template/en/default/list/list.html.tmpl b/template/en/default/list/list.html.tmpl
index 8d67e6c41..467e4dfc7 100644
--- a/template/en/default/list/list.html.tmpl
+++ b/template/en/default/list/list.html.tmpl
@@ -28,7 +28,7 @@
[%# Template Initialization #%]
[%############################################################################%]
-[% PROCESS global/variables.none.tmpl %]
+[% PROCESS "global/field-descs.none.tmpl" %]
[% title = "$terms.Bug List" %]
[% IF searchname || defaultsavename %]
@@ -58,11 +58,6 @@
</span>
[% IF debug %]
- <p class="bz_query_debug">
- [% FOREACH debugline = debugdata %]
- [% debugline FILTER html %]<br>
- [% END %]
- </p>
<p class="bz_query">[% query FILTER html %]</p>
[% IF query_explain.defined %]
<pre class="bz_query_explain">[% query_explain FILTER html %]</pre>
@@ -85,6 +80,26 @@
</h2>
[% END %]
+[% SET shown_types = [
+ 'notequal', 'regexp', 'notregexp', 'lessthan', 'lessthaneq',
+ 'greaterthan', 'greaterthaneq', 'changedbefore', 'changedafter',
+ 'changedfrom', 'changedto', 'changedby',
+] %]
+<ul class="search_description">
+[% FOREACH desc_item = search_description %]
+ <li>
+ <strong>[% field_descs.${desc_item.field} FILTER html %]:</strong>
+ [% IF shown_types.contains(desc_item.type) || debug %]
+ ([% search_descs.${desc_item.type} FILTER html %])
+ [% END %]
+ [%+ desc_item.value FILTER html %]
+ [% IF debug %]
+ (<code>[% desc_item.term FILTER html %]</code>)
+ [% END %]
+ </li>
+[% END %]
+</ul>
+
<hr>
[%############################################################################%]
diff --git a/template/en/default/search/boolean-charts.html.tmpl b/template/en/default/search/boolean-charts.html.tmpl
index 97a10d4ab..db21be681 100644
--- a/template/en/default/search/boolean-charts.html.tmpl
+++ b/template/en/default/search/boolean-charts.html.tmpl
@@ -17,31 +17,34 @@
#
# Contributor(s): Gervase Markham <gerv@gerv.net>
#%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
[% types = [
- { name => "noop", description => "---" },
- { name => "equals", description => "is equal to" },
- { name => "notequals", description => "is not equal to" },
- { name => "anyexact", description => "is equal to any of the strings" },
- { name => "substring", description => "contains the string" },
- { name => "casesubstring", description => "contains the string (exact case)" },
- { name => "notsubstring", description => "does not contain the string" },
- { name => "anywordssubstr", description => "contains any of the strings" },
- { name => "allwordssubstr", description => "contains all of the strings" },
- { name => "nowordssubstr", description => "contains none of the strings" },
- { name => "regexp", description => "contains regexp" },
- { name => "notregexp", description => "does not contain regexp" },
- { name => "lessthan", description => "is less than" },
- { name => "greaterthan", description => "is greater than" },
- { name => "anywords", description => "contains any of the words" },
- { name => "allwords", description => "contains all of the words" },
- { name => "nowords", description => "contains none of the words" },
- { name => "changedbefore", description => "changed before" },
- { name => "changedafter", description => "changed after" },
- { name => "changedfrom", description => "changed from" },
- { name => "changedto", description => "changed to" },
- { name => "changedby", description => "changed by" },
- { name => "matches", description => "matches" } ] %]
+ "noop",
+ "equals",
+ "notequals",
+ "anyexact",
+ "substring",
+ "casesubstring",
+ "notsubstring",
+ "anywordssubstr",
+ "allwordssubstr",
+ "nowordssubstr",
+ "regexp",
+ "notregexp",
+ "lessthan",
+ "greaterthan",
+ "anywords",
+ "allwords",
+ "nowords",
+ "changedbefore",
+ "changedafter",
+ "changedfrom",
+ "changedto",
+ "changedby",
+ "matches",
+] %]
<p>
<strong>
@@ -80,12 +83,9 @@
[% END %]
</select>
- <select name="[% "type${chartnum}-${rownum}-${colnum}" %]">
- [% FOREACH type = types %]
- <option value="[% type.name %]"
- [%- " selected" IF type.name == col.type %]>[% type.description %]</option>
- [% END %]
- </select>
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = "type${chartnum}-${rownum}-${colnum}",
+ types = types, selected = col.type %]
<input name="[% "value${chartnum}-${rownum}-${colnum}" %]"
value="[% col.value FILTER html %]">
diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl
index 05b52dca4..46df426c1 100644
--- a/template/en/default/search/form.html.tmpl
+++ b/template/en/default/search/form.html.tmpl
@@ -20,6 +20,8 @@
# Gervase Markham <gerv@gerv.net>
#%]
+[% PROCESS "global/field-descs.none.tmpl" %]
+
<script type="text/javascript">
var first_load = true; [%# is this the first time we load the page? %]
@@ -103,20 +105,16 @@ function doOnSelectProduct(selectmode) {
</script>
-
-[% PROCESS global/variables.none.tmpl %]
-
-[% query_variants = [
- { value => "allwordssubstr", description => "contains all of the words/strings" },
- { value => "anywordssubstr", description => "contains any of the words/strings" },
- { value => "substring", description => "contains the string" },
- { value => "casesubstring", description => "contains the string (exact case)" },
- { value => "allwords", description => "contains all of the words" },
- { value => "anywords", description => "contains any of the words" },
- { value => "regexp", description => "matches the regexp" },
- { value => "notregexp", description => "doesn't match the regexp" } ] %]
-
-[% PROCESS "global/field-descs.none.tmpl" %]
+[% query_types = [
+ "allwordssubstr",
+ "anywordssubstr",
+ "substring",
+ "casesubstring",
+ "allwords",
+ "anywords",
+ "regexp",
+ "notregexp",
+] %]
[%# If we resubmit to ourselves, we need to know if we are using a format. %]
[% thisformat = query_format != '' ? query_format : format %]
@@ -130,12 +128,9 @@ function doOnSelectProduct(selectmode) {
<label for="short_desc" accesskey="s"><u>S</u>ummary</label>:
</th>
<td>
- <select name="short_desc_type">
- [% FOREACH qv = query_variants %]
- <option value="[% qv.value %]"
- [% " selected" IF default.short_desc_type.0 == qv.value %]>[% qv.description %]</option>
- [% END %]
- </select>
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = "short_desc_type",
+ types = query_types, selected = default.short_desc_type.0 %]
</td>
<td>
<input name="short_desc" id="short_desc" size="40"
@@ -265,7 +260,7 @@ function doOnSelectProduct(selectmode) {
[%# *** Comment URL Whiteboard Keywords *** %]
[% FOREACH field = [
- { name => "long_desc", description => "A&nbsp;<u>C</u>omment",
+ { name => "longdesc", description => "A&nbsp;<u>C</u>omment",
accesskey => 'c' },
{ name => "bug_file_loc", description => "The&nbsp;<u>U</u>RL",
accesskey => 'u' },
@@ -278,13 +273,9 @@ function doOnSelectProduct(selectmode) {
<label for="[% field.name %]" accesskey="[% field.accesskey %]">[% field.description %]</label>:
</th>
<td>
- <select name="[% field.name %]_type">
- [% FOREACH qv = query_variants %]
- [% type = "${field.name}_type" %]
- <option value="[% qv.value %]"
- [% " selected" IF default.$type.0 == qv.value %]>[% qv.description %]</option>
- [% END %]
- </select>
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = field.name _ "_type",
+ types = query_types, selected = default.$type.0 %]
</td>
<td><input name="[% field.name %]" id="[% field.name %]" size="40"
value="[% default.${field.name}.0 FILTER html %]">
@@ -300,17 +291,10 @@ function doOnSelectProduct(selectmode) {
<label for="keywords" accesskey="k"><a href="describekeywords.cgi"><u>K</u>eywords</a></label>:
</th>
<td>
- <select name="keywords_type">
- [% FOREACH qv = [
- { name => "allwords", description => "contains all of the keywords" },
- { name => "anywords", description => "contains any of the keywords" },
- { name => "nowords", description => "contains none of the keywords" } ] %]
-
- <option value="[% qv.name %]"
- [% " selected" IF default.keywords_type.0 == qv.name %]>
- [% qv.description %]</option>
- [% END %]
- </select>
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = "keywords_type",
+ types = ['allwords', 'anywords', 'nowords'],
+ selected = default.keywords_type.0 %]
</td>
<td>
<input name="keywords" id="keywords" size="40"
diff --git a/template/en/default/search/type-select.html.tmpl b/template/en/default/search/type-select.html.tmpl
new file mode 100644
index 000000000..e74cc3cd3
--- /dev/null
+++ b/template/en/default/search/type-select.html.tmpl
@@ -0,0 +1,29 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the Bugzilla Bug Tracking System.
+ #
+ # The Initial Developer of the Original Code is the San Jose State
+ # University Foundation. Portions created by the Initial Developer are
+ # Copyright (C) 2008 the Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s):
+ # Max Kanat-Alexander <mkanat@bugzilla.org>
+ #%]
+
+[% PROCESS "global/field-descs.none.tmpl" %]
+
+<select name="[% name FILTER html %]">
+ [% FOREACH type = types %]
+ <option value="[% type FILTER html %]"
+ [%- ' selected="selected"' IF type == selected %]>
+ [%- search_descs.$type %]</option>
+ [% END %]
+</select>