Bug 160410: defparams.pl support for single/multi pulldown menus; p=preed,r=joel,r2=bbaetz

This commit is contained in:
preed%sigkill.com 2002-08-11 14:12:33 +00:00
parent f9592936f1
commit 9174906a99
4 changed files with 214 additions and 29 deletions

View File

@ -22,6 +22,7 @@
# Dan Mosedale <dmose@mozilla.org>
# Joe Robins <jmrobins@tgix.com>
# Jake <jake@acutex.net>
# J. Paul Reed <preed@sigkill.com>
#
# This file defines all the parameters that we have a GUI to edit within
@ -43,12 +44,34 @@ sub defparams_pl_sillyness {
$zz = %::param_checker;
$zz = %::param_desc;
$zz = %::param_type;
$zz = %::MFORM;
}
sub WriteParams {
foreach my $i (@::param_list) {
if (!defined $::param{$i}) {
$::param{$i} = $::param_default{$i};
if ($::param_type{$i} eq "m") {
## For list params (single or multi), param_default is an array
## with the second element as the default; we have to loop
## through it to get them all for multi lists and we have to
## select the second one by itself for single list (next branch
## of the if)
my $multiParamStr = "[ ";
foreach my $defaultParam (@{$::param_default{$i}->[1]}) {
$multiParamStr .= "'$defaultParam', ";
}
$multiParamStr .= " ]";
$::param{$i} = $multiParamStr;
}
elsif ($::param_type{$i} eq "s") {
$::param{$i} = $::param_default{$i}->[1];
}
else {
$::param{$i} = $::param_default{$i};
}
if (!defined $::param{$i}) {
die "No default parameter ever specified for $i";
}
@ -67,7 +90,11 @@ sub WriteParams {
rename $tmpname, "data/params" || die "Can't rename $tmpname to data/params";
ChmodDataFile('data/params', 0666);
}
## $checker is a CODE ref that points to a function that verifies the
## parameter for validity; it is called by doeditparams.cgi with the value
## of the param as the first arg and the param name as the 2nd arg (which
## many checker functions ignore, but a couple of them need it.
sub DefParam {
my ($id, $desc, $type, $default, $checker) = (@_);
@ -80,6 +107,57 @@ sub DefParam {
}
}
## Converts text parameters for single- and multi-select type params to their
## array indices; takes the name of the parameter and the value you want the
## index of; returns undef on failure.
sub get_select_param_index {
my ($paramName, $val) = (@_);
return undef if ($::param_type{$paramName} !~ /^m|s$/);
my $paramList = $::param_default{$paramName}->[0];
for (my $ndx = 0; $ndx < scalar(@{$paramList}); $ndx++) {
## The first element of the $param_default array in selects is the
## list of possible params; search through this array for a match.
return $ndx if ($val eq $paramList->[$ndx]);
}
return undef;
}
sub check_multi {
my ($value, $param) = (@_);
if ($::param_type{$param} eq "s") {
if (check_numeric($value) ne "") {
return "List param types must be digits";
}
elsif ($value < 0 || $value > $#{$::param_default{$param}->[0]}) {
return "Invalid choice for single-select list param '$param'";
}
else {
return "";
}
}
elsif ($::param_type{$param} eq "m") {
foreach my $chkParam (@{$::MFORM{$param}}) {
if (check_numeric($chkParam) ne "") {
return "List param types must be digits";
}
elsif ($chkParam < 0 || $chkParam >
$#{$::param_default{$param}->[0]}) {
return "Invalid choice for multi-select list param '$param'";
}
}
return "";
}
else {
return "Invalid param type for check_multi(); contact your BZ admin";
}
}
sub check_numeric {
my ($value) = (@_);
@ -119,6 +197,33 @@ sub check_shadowdb {
# t -- A short text entry field (suitable for a single line)
# l -- A long text field (suitable for many lines)
# b -- A boolean value (either 1 or 0)
# m -- A list of values, with many selectable (shows up as a select box)
# To specify the list of values, make the 'default value' for DefParam()
# a reference to two anonymous arrays, the first being the list of options
# and the second being a list of defaults (which must appear in the
# first anonymous array), i.e.:
# DefParam("multiselect", "A list of options, choose many",
# "m", [ ['a','b','c','d'], ['a', 'd'] ], \&check_multi);
#
# Here, 'a' and 'd' are the default options, and the user may pick any
# combination of a, b, c, and d as valid options.
#
# &check_multi should always be used as the param verification function
# for list (single and multiple) parameter types.
#
# s -- A list of values, with one selectable (shows up as a select box)
# To specify the list of values, make the default value a reference to
# an anonymous array with two items inside of it, the first being an
# array of the possible values and the second being the scalar that is
# the default default value, i.e.:
# DefParam("singleselect", "A list of options, choose one", "s",
# [ ['a','b','c'], 'b'], \&check_multi);
#
# Here, 'b' is the default option, and 'a' and 'c' are other possible
# options, but only one at a time!
#
# &check_multi should always be used as the param verification function
# for list (single and multiple) parameter types.
DefParam("maintainer",
"The email address of the person who maintains this installation of Bugzilla.",

View File

@ -19,6 +19,7 @@
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# J. Paul Reed <preed@sigkill.com>
use diagnostics;
use strict;
@ -51,14 +52,30 @@ PutHeader("Saving new parameters");
foreach my $i (@::param_list) {
# print "Processing $i...<BR>\n";
if (exists $::FORM{"reset-$i"}) {
$::FORM{$i} = $::param_default{$i};
if ($::param_type{$i} eq "s") {
my $index = get_select_param_index($i, $::param_default{$i}->[1]);
die "Param not found for '$i'" if ($index eq undef);
$::FORM{$i} = $index;
}
elsif ($::param_type{$i} eq "m") {
# For 'multi' selects, default is the 2nd anon array of the default
@{$::MFORM{$i}} = ();
foreach my $defaultPrm (@{$::param_default{$i}->[1]}) {
my $index = get_select_param_index($i, $defaultPrm);
die "Param not found for '$i'" if ($index eq undef);
push(@{$::MFORM{$i}}, $index);
}
}
else {
$::FORM{$i} = $::param_default{$i};
}
}
$::FORM{$i} =~ s/\r\n?/\n/g; # Get rid of windows/mac-style line endings.
$::FORM{$i} =~ s/^\n$//; # assume single linefeed is an empty string
if ($::FORM{$i} ne Param($i)) {
if (defined $::param_checker{$i}) {
my $ref = $::param_checker{$i};
my $ok = &$ref($::FORM{$i});
my $ok = &$ref($::FORM{$i}, $i);
if ($ok ne "") {
print "New value for $i is invalid: $ok<p>\n";
print "Please hit <b>Back</b> and try again.\n";
@ -69,7 +86,22 @@ foreach my $i (@::param_list) {
print "Changed $i.<br>\n";
# print "Old: '" . url_quote(Param($i)) . "'<BR>\n";
# print "New: '" . url_quote($::FORM{$i}) . "'<BR>\n";
$::param{$i} = $::FORM{$i};
if ($::param_type{$i} eq "s") {
$::param{$i} = $::param_default{$i}->[0]->[$::FORM{$i}];
}
elsif ($::param_type{$i} eq "m") {
my $multiParamStr = "[ ";
foreach my $chosenParam (@{$::MFORM{$i}}) {
$multiParamStr .=
"'$::param_default{$i}->[0]->[$chosenParam]', ";
}
$multiParamStr .= " ]";
$::param{$i} = $multiParamStr;
}
else {
$::param{$i} = $::FORM{$i};
}
}
}

View File

@ -19,6 +19,7 @@
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# J. Paul Reed <preed@sigkill.com>
use diagnostics;
@ -30,7 +31,8 @@ require "defparams.pl";
# Shut up misguided -w warnings about "used only once":
use vars @::param_desc,
@::param_list;
@::param_list,
@::param_default;
ConnectToDatabase();
confirm_login();
@ -87,6 +89,48 @@ foreach my $i (@::param_list) {
print "<input type=radio name=$i value=0 $off>Off\n";
last SWITCH;
};
/^m$/ && do {
my $optList = $::param_default{$i}->[0]; #'cause we use it so much
## showing 5 options seems like a nice round number; this should
## probably be configurable; if you care, file a bug ;-)
my $boxSize = scalar(@{$optList}) < 5 ? scalar(@{$optList}) : 5;
print "<select multiple size=\"$boxSize\" name=\"$i\">\n";
for (my $optNum = 0; $optNum < scalar(@{$optList}); $optNum++) {
my $selected = "";
foreach my $selectedVal (@{$value}) {
if ($selectedVal eq $optList->[$optNum]) {
$selected = "selected";
last;
}
}
print "<option $selected value=\"$optNum\">" .
"$optList->[$optNum]</option>\n";
}
print "</select>\n";
last SWITCH;
};
/^s$/ && do {
print "<select name=\"$i\">\n";
#'cause we use it so much below
my $optList = $::param_default{$i}->[0];
for (my $optNum = 0; $optNum < scalar(@{$optList}); $optNum++) {
my $selected = "";
if ($value eq $optList->[$optNum]) {
$selected = "selected";
}
print "<option $selected value=\"$optNum\">" .
"$optList->[$optNum]</option>\n";
}
print "</select>\n";
last SWITCH;
};
# DEFAULT
print "<font color=red><blink>Unknown param type $::param_type{$i}!!!</blink></font>\n";
}

View File

@ -1413,36 +1413,40 @@ sub RemoveVotes {
}
}
sub Param ($) {
my ($value) = (@_);
if (defined $::param{$value}) {
return $::param{$value};
if (! defined $::param{$value}) {
# Um, maybe we haven't sourced in the params at all yet.
if (stat("data/params")) {
# Write down and restore the version # here. That way, we get
# around anyone who maliciously tries to tweak the version number
# by editing the params file. Not to mention that in 2.0, there
# was a bug that wrote the version number out to the params file...
my $v = $::param{'version'};
require "data/params";
$::param{'version'} = $v;
}
}
# Um, maybe we haven't sourced in the params at all yet.
if (stat("data/params")) {
# Write down and restore the version # here. That way, we get around
# anyone who maliciously tries to tweak the version number by editing
# the params file. Not to mention that in 2.0, there was a bug that
# wrote the version number out to the params file...
my $v = $::param{'version'};
require "data/params";
$::param{'version'} = $v;
if (! defined $::param{$value}) {
# Well, that didn't help. Maybe it's a new param, and the user
# hasn't defined anything for it. Try and load a default value
# for it.
require "defparams.pl";
WriteParams();
}
if (defined $::param{$value}) {
# If it's still not defined, we're pimped.
die "Can't find param named $value" if (! defined $::param{$value});
if ($::param_type{$value} eq "m") {
my $valueList = eval($::param{$value});
return $valueList if (!($@) && ref($valueList) eq "ARRAY");
die "Multi-list param '$value' eval() failure ('$@'); data/params is horked";
}
else {
return $::param{$value};
}
# Well, that didn't help. Maybe it's a new param, and the user
# hasn't defined anything for it. Try and load a default value
# for it.
require "defparams.pl";
WriteParams();
if (defined $::param{$value}) {
return $::param{$value};
}
# We're pimped.
die "Can't find param named $value";
}
# Take two comma or space separated strings and return what