#!/usr/bonsaitools/bin/perl -w # -*- Mode: perl; indent-tabs-mode: nil -*- # # 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 Netscape Communications # Corporation. Portions created by Netscape are # Copyright (C) 1998 Netscape Communications Corporation. All # Rights Reserved. # # Contributor(s): Terry Weissman # David Gardiner # Matthias Radestock # Chris Lahey [javascript fixes] # Christian Reis [javascript rewrite] use diagnostics; use strict; require "CGI.pl"; $::CheckOptionValues = 0; # It's OK if we have some bogus things in the # pop-up lists here, from a remembered query # that is no longer quite valid. We don't # want to crap out in the query page. # Shut up misguided -w warnings about "used only once": use vars @::CheckOptionValues, @::legal_resolution, @::legal_bug_status, @::legal_components, @::legal_keywords, @::legal_opsys, @::legal_platform, @::legal_priority, @::legal_product, @::legal_severity, @::legal_target_milestone, @::legal_versions, @::log_columns, %::versions, %::components, %::FORM; if (defined $::FORM{"GoAheadAndLogIn"}) { # We got here from a login page, probably from relogin.cgi. We better # make sure the password is legit. confirm_login(); } else { quietly_check_login(); } my $userid = 0; if (defined $::COOKIE{"Bugzilla_login"}) { $userid = DBNameToIdAndCheck($::COOKIE{"Bugzilla_login"}); } # Backwards compatability hack -- if there are any of the old QUERY_* # cookies around, and we are logged in, then move them into the database # and nuke the cookie. if ($userid) { my @oldquerycookies; foreach my $i (keys %::COOKIE) { if ($i =~ /^QUERY_(.*)$/) { push(@oldquerycookies, [$1, $i, $::COOKIE{$i}]); } } if (defined $::COOKIE{'DEFAULTQUERY'}) { push(@oldquerycookies, [$::defaultqueryname, 'DEFAULTQUERY', $::COOKIE{'DEFAULTQUERY'}]); } if (@oldquerycookies) { foreach my $ref (@oldquerycookies) { my ($name, $cookiename, $value) = (@$ref); if ($value) { my $qname = SqlQuote($name); SendSQL("SELECT query FROM namedqueries " . "WHERE userid = $userid AND name = $qname"); my $query = FetchOneColumn(); if (!$query) { SendSQL("REPLACE INTO namedqueries " . "(userid, name, query) VALUES " . "($userid, $qname, " . SqlQuote($value) . ")"); } } print "Set-Cookie: $cookiename= ; path=/ ; expires=Sun, 30-Jun-1980 00:00:00 GMT\n"; } } } if ($::FORM{'nukedefaultquery'}) { if ($userid) { SendSQL("DELETE FROM namedqueries " . "WHERE userid = $userid AND name = '$::defaultqueryname'"); } $::buffer = ""; } my $userdefaultquery; if ($userid) { SendSQL("SELECT query FROM namedqueries " . "WHERE userid = $userid AND name = '$::defaultqueryname'"); $userdefaultquery = FetchOneColumn(); } my %default; my %type; sub ProcessFormStuff { my ($buf) = (@_); my $foundone = 0; foreach my $name ("bug_status", "resolution", "assigned_to", "rep_platform", "priority", "bug_severity", "product", "reporter", "op_sys", "component", "version", "chfield", "chfieldfrom", "chfieldto", "chfieldvalue", "target_milestone", "email1", "emailtype1", "emailreporter1", "emailassigned_to1", "emailcc1", "emailqa_contact1", "emaillongdesc1", "email2", "emailtype2", "emailreporter2", "emailassigned_to2", "emailcc2", "emailqa_contact2", "emaillongdesc2", "changedin", "votes", "short_desc", "short_desc_type", "long_desc", "long_desc_type", "bug_file_loc", "bug_file_loc_type", "status_whiteboard", "status_whiteboard_type", "bug_id", "bugidtype", "keywords", "keywords_type") { $default{$name} = ""; $type{$name} = 0; } foreach my $item (split(/\&/, $buf)) { my @el = split(/=/, $item); my $name = $el[0]; my $value; if ($#el > 0) { $value = url_decode($el[1]); } else { $value = ""; } if (defined $default{$name}) { $foundone = 1; if ($default{$name} ne "") { $default{$name} .= "|$value"; $type{$name} = 1; } else { $default{$name} = $value; } } } return $foundone; } if (!ProcessFormStuff($::buffer)) { # Ah-hah, there was no form stuff specified. Do it again with the # default query. if ($userdefaultquery) { ProcessFormStuff($userdefaultquery); } else { ProcessFormStuff(Param("defaultquery")); } } if ($default{'chfieldto'} eq "") { $default{'chfieldto'} = "Now"; } print "Set-Cookie: BUGLIST= Content-type: text/html\n\n"; GetVersionTable(); sub GenerateEmailInput { my ($id) = (@_); my $defstr = value_quote($default{"email$id"}); my $deftype = $default{"emailtype$id"}; if ($deftype eq "") { $deftype = "substring"; } my $assignedto = ($default{"emailassigned_to$id"} eq "1") ? "checked" : ""; my $reporter = ($default{"emailreporter$id"} eq "1") ? "checked" : ""; my $cc = ($default{"emailcc$id"} eq "1") ? "checked" : ""; my $longdesc = ($default{"emaillongdesc$id"} eq "1") ? "checked" : ""; my $qapart = ""; my $qacontact = ""; if (Param("useqacontact")) { $qacontact = ($default{"emailqa_contact$id"} eq "1") ? "checked" : ""; $qapart = qq| QA Contact |; } if ($assignedto eq "" && $reporter eq "" && $cc eq "" && $qacontact eq "") { if ($id eq "1") { $assignedto = "checked"; } else { $reporter = "checked"; } } $default{"emailtype$id"} ||= "substring"; return qq{
$qapart
Email:  matching as } . BuildPulldown("emailtype$id", [["regexp", "regexp"], ["notregexp", "not regexp"], ["substring", "substring"], ["exact", "exact"]], $default{"emailtype$id"}) . qq{ Assigned To
Reporter
(Will match any of the selected fields) CC
Added comment
}; } my $emailinput1 = GenerateEmailInput(1); my $emailinput2 = GenerateEmailInput(2); # if using usebuggroups, then we don't want people to see products they don't # have access to. remove them from the list. @::product_list = (); my %component_set; my %version_set; my %milestone_set; foreach my $p (@::legal_product) { if(Param("usebuggroups") && GroupExists($p) && !UserInGroup($p)) { # If we're using bug groups to restrict entry on products, and # this product has a bug group, and the user is not in that # group, we don't want to include that product in this list. next; } push @::product_list, $p; if ($::components{$p}) { foreach my $c (@{$::components{$p}}) { $component_set{$c} = 1; } } foreach my $v (@{$::versions{$p}}) { $version_set{$v} = 1; } foreach my $m (@{$::target_milestone{$p}}) { $milestone_set{$m} = 1; } } @::component_list = (); @::version_list = (); @::milestone_list = (); foreach my $c (@::legal_components) { if ($component_set{$c}) { push @::component_list, $c; } } foreach my $v (@::legal_versions) { if ($version_set{$v}) { push @::version_list, $v; } } foreach my $m (@::legal_target_milestone) { if ($milestone_set{$m}) { push @::milestone_list, $m; } } # SELECT box javascript handling. This is done to make the component, # versions and milestone SELECTs repaint automatically when a product is # selected. Refactored for bug 96534. # make_js_array: iterates through the product array creating a # javascript array keyed by product with an alphabetically ordered array # for the corresponding elements in the components array passed in. # return a string with javascript definitions for the product in a nice # arrays which can be linearly appended later on. # make_js_array ( \@products, \%[components/versions/milestones], $array ) sub make_js_array { my @prods = @{$_[0]}; my %data = %{$_[1]}; my $arr = $_[2]; my $ret = "\nvar $arr = new Array();\n"; foreach my $p ( @prods ) { # join each element with a "," case-insensitively alpha sorted if ( $data{$p} ) { $ret .= $arr."[".SqlQuote($p)."] = ["; # the SqlQuote() protects our 's. my @tmp = map( SqlQuote( $_ ), @{ $data{$p} } ); # do the join on a sorted, quoted list @tmp = sort { lc( $a ) cmp lc( $b ) } @tmp; $ret .= join( ", ", @tmp ); $ret .= "];\n"; } } return $ret; } my $jscript = ' ENDSCRIPT # # End the fearsome Javascript section. # # Muck the "legal product" list so that the default one is always first (and # is therefore visibly selected. # Commented out, until we actually have enough products for this to matter. # set w [lsearch $legal_product $default{"product"}] # if {$w >= 0} { # set legal_product [concat $default{"product"} [lreplace $legal_product $w $w]] # } PutHeader("Bugzilla Query Page", "Query", "This page lets you search the database for recorded bugs.", q{onLoad="selectProduct(document.forms['queryform']);"}, $jscript); push @::legal_resolution, "---"; # Oy, what a hack. my @logfields = ("[Bug creation]", @::log_columns); print"

Give me a clue about how to use this form.

"; print qq{

}; print "
Status: Resolution: Platform: OpSys: Priority: Severity:
@{[make_selection_widget(\"bug_status\",\@::legal_bug_status,$default{'bug_status'}, $type{'bug_status'}, 1)]} @{[make_selection_widget(\"resolution\",\@::legal_resolution,$default{'resolution'}, $type{'resolution'}, 1)]} @{[make_selection_widget(\"rep_platform\",\@::legal_platform,$default{'platform'}, $type{'platform'}, 1)]} @{[make_selection_widget(\"op_sys\",\@::legal_opsys,$default{'op_sys'}, $type{'op_sys'}, 1)]} @{[make_selection_widget(\"priority\",\@::legal_priority,$default{'priority'}, $type{'priority'}, 1)]} @{[make_selection_widget(\"bug_severity\",\@::legal_severity,$default{'bug_severity'}, $type{'bug_severity'}, 1)]}

"; my $inclselected = "SELECTED"; my $exclselected = ""; if ($default{'bugidtype'} eq "exclude") { $inclselected = ""; $exclselected = "SELECTED"; } my $bug_id = value_quote($default{'bug_id'}); print qq{ }; print "
$emailinput1

$emailinput2

bugs numbered:
Changed in the last days. At least votes.
Where the field(s) changed. dates to
changed to value (optional)

"; if (Param("usetargetmilestone")) { print ""; } print " "; if (Param("usetargetmilestone")) { print " "; } sub StringSearch { my ($desc, $name) = (@_); my $type = $name . "_type"; my $def = value_quote($default{$name}); print qq{ "; } print "
Program: Version: Component:Target Milestone:
$desc:
"; StringSearch("Summary", "short_desc"); StringSearch("A description entry", "long_desc"); StringSearch("URL", "bug_file_loc"); if (Param("usestatuswhiteboard")) { StringSearch("Status whiteboard", "status_whiteboard"); } if (@::legal_keywords) { my $def = value_quote($default{'keywords'}); print qq{ }; } print "
Keywords: }; my $type = $default{"keywords_type"}; if ($type eq "or") { # Backward compatability hack. $type = "anywords"; } print BuildPulldown("keywords_type", [["anywords", "Any of the listed keywords set"], ["allwords", "All of the listed keywords set"], ["nowords", "None of the listed keywords set"]], $type); print qq{

"; my @fields; push(@fields, ["noop", "---"]); ConnectToDatabase(); SendSQL("SELECT name, description FROM fielddefs ORDER BY sortkey"); while (MoreSQLData()) { my ($name, $description) = (FetchSQLData()); push(@fields, [$name, $description]); } my @types = ( ["noop", "---"], ["equals", "equal to"], ["notequals", "not equal to"], ["casesubstring", "contains (case-sensitive) substring"], ["substring", "contains (case-insensitive) substring"], ["notsubstring", "does not contain (case-insensitive) substring"], ["allwordssubstr", "all words as (case-insensitive) substrings"], ["anywordssubstr", "any words as (case-insensitive) substrings"], ["regexp", "contains regexp"], ["notregexp", "does not contain regexp"], ["lessthan", "less than"], ["greaterthan", "greater than"], ["anywords", "any words"], ["allwords", "all words"], ["nowords", "none of the words"], ["changedbefore", "changed before"], ["changedafter", "changed after"], ["changedfrom", "changed from"], ["changedto", "changed to"], ["changedby", "changed by"], ); print qq{ \n}; foreach my $cmd (grep(/^cmd-/, keys(%::FORM))) { if ($cmd =~ /^cmd-add(\d+)-(\d+)-(\d+)$/) { $::FORM{"field$1-$2-$3"} = "xyzzy"; } } # foreach my $i (sort(keys(%::FORM))) { # print "$i : " . value_quote($::FORM{$i}) . "
\n"; # } if (!exists $::FORM{'field0-0-0'}) { $::FORM{'field0-0-0'} = "xyzzy"; } my $jsmagic = qq{ONCLICK="document.forms[0].action='query.cgi#chart' ; document.forms[0].method='POST' ; return 1;"}; my $chart; for ($chart=0 ; exists $::FORM{"field$chart-0-0"} ; $chart++) { my @rows; my $row; for ($row = 0 ; exists $::FORM{"field$chart-$row-0"} ; $row++) { my @cols; my $col; for ($col = 0 ; exists $::FORM{"field$chart-$row-$col"} ; $col++) { my $key = "$chart-$row-$col"; my $deffield = $::FORM{"field$key"} || ""; my $deftype = $::FORM{"type$key"} || ""; my $defvalue = value_quote($::FORM{"value$key"} || ""); my $line = ""; $line .= ""; $line .= BuildPulldown("field$key", \@fields, $deffield); $line .= BuildPulldown("type$key", \@types, $deftype); $line .= qq{}; $line .= "\n"; push(@cols, $line); } push(@rows, "" . join(qq{ or \n}, @cols) . qq{}); } print qq{


}; print join('', @rows); print qq{
And
}; my $n = $chart + 1; if (!exists $::FORM{"field$n-0-0"}) { print qq{             What is this stuff? }; } print qq{
}; } print qq{
}; if (!$userid) { print qq{}; } else { print "
Run this query
"; my @namedqueries; if ($userid) { SendSQL("SELECT name FROM namedqueries " . "WHERE userid = $userid AND name != '$::defaultqueryname' " . "ORDER BY name"); while (MoreSQLData()) { push(@namedqueries, FetchOneColumn()); } } if (@namedqueries) { my $namelist = make_options(\@namedqueries); print qq{
Load the remembered query:
Run the remembered query:
Forget the remembered query:
}; } print qq{ Remember this as the default query
Remember this query, and name it:
     and put it in my page footer.
}; } print qq{ Sort By: "; if ($userdefaultquery) { print qq{
Set my default query back to the system default}; } print "
"; ### ### I really hate this redudancy, but if somebody for some inexplicable reason doesn't like using ### the footer for these links, they can uncomment this section. ### # if (UserInGroup("tweakparams")) { # print "Edit Bugzilla operating parameters
\n"; # } # if (UserInGroup("editcomponents")) { # print "Edit Bugzilla products and components
\n"; # } # if (UserInGroup("editkeywords")) { # print "Edit Bugzilla keywords
\n"; # } # if ($userid) { # print "Log in as someone besides $::COOKIE{'Bugzilla_login'}
\n"; # } # print "Change your password or preferences.
\n"; # print "Report a new bug.
\n"; # print "Open a new Bugzilla account
\n"; # print "Bug reports
\n"; PutFooter();