diff options
-rw-r--r-- | defparams.pl | 109 | ||||
-rwxr-xr-x | doeditparams.cgi | 38 | ||||
-rwxr-xr-x | editparams.cgi | 46 | ||||
-rw-r--r-- | globals.pl | 48 |
4 files changed, 213 insertions, 28 deletions
diff --git a/defparams.pl b/defparams.pl index 3e3fd441d..5a1abdc43 100644 --- a/defparams.pl +++ b/defparams.pl @@ -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.", diff --git a/doeditparams.cgi b/doeditparams.cgi index 3e97e140b..c237a1997 100755 --- a/doeditparams.cgi +++ b/doeditparams.cgi @@ -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}; + } } } diff --git a/editparams.cgi b/editparams.cgi index 40f5ad537..0e1b7161f 100755 --- a/editparams.cgi +++ b/editparams.cgi @@ -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"; } diff --git a/globals.pl b/globals.pl index 6f7b22d38..9e2311a83 100644 --- a/globals.pl +++ b/globals.pl @@ -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}) { - return $::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"; } - # 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}) { + else { return $::param{$value}; } - # We're pimped. - die "Can't find param named $value"; } # Take two comma or space separated strings and return what |