summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortravis%sedsystems.ca <>2005-03-11 00:51:40 +0100
committertravis%sedsystems.ca <>2005-03-11 00:51:40 +0100
commit6674f61905d98aee08b95c22181aa439bfb041e5 (patch)
tree1b220ecddbfbc5a433982841508571696e211c60
parent9ffc6eb52bb9c549dae85a51aaf2b29750b7ba14 (diff)
downloadbugzilla-6674f61905d98aee08b95c22181aa439bfb041e5.tar.gz
bugzilla-6674f61905d98aee08b95c22181aa439bfb041e5.tar.xz
Bug 98123 : Create a user preferences infrastructure (became 'General Settings')
Patch by Shane H. W. Travis <travis@sedsystems.ca> r=jouni, mkanat a=myk
-rw-r--r--Bugzilla/DB/Schema.pm49
-rw-r--r--Bugzilla/User.pm33
-rw-r--r--Bugzilla/User/Setting.pm352
-rwxr-xr-xchecksetup.pl4
-rwxr-xr-xeditsettings.cgi107
-rw-r--r--template/en/default/account/prefs/prefs.html.tmpl2
-rw-r--r--template/en/default/account/prefs/settings.html.tmpl63
-rw-r--r--template/en/default/admin/settings/edit.html.tmpl102
-rw-r--r--template/en/default/admin/settings/updated.html.tmpl27
-rw-r--r--template/en/default/filterexceptions.pl10
-rw-r--r--template/en/default/global/code-error.html.tmpl9
-rw-r--r--template/en/default/global/field-descs.none.tmpl2
-rw-r--r--template/en/default/global/setting-descs.none.tmpl26
-rw-r--r--template/en/default/global/useful-links.html.tmpl3
-rwxr-xr-xuserprefs.cgi39
15 files changed, 827 insertions, 1 deletions
diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm
index 3a15a755e..99f5f106f 100644
--- a/Bugzilla/DB/Schema.pm
+++ b/Bugzilla/DB/Schema.pm
@@ -913,6 +913,55 @@ use constant ABSTRACT_SCHEMA => {
],
},
+ # SETTINGS
+ # --------
+ # setting - each global setting will have exactly one entry
+ # in this table.
+ # setting_value - stores the list of acceptable values for each
+ # setting, and a sort index that controls the order
+ # in which the values are displayed.
+ # profile_setting - If a user has chosen to use a value other than the
+ # global default for a given setting, it will be
+ # stored in this table. Note: even if a setting is
+ # later changed so is_enabled = false, the stored
+ # value will remain in case it is ever enabled again.
+ #
+ setting => {
+ FIELDS => [
+ name => {TYPE => 'varchar(32)', NOTNULL => 1,
+ PRIMARYKEY => 1},
+ default_value => {TYPE => 'varchar(32)', NOTNULL => 1},
+ is_enabled => {TYPE => 'BOOLEAN', NOTNULL => 1,
+ DEFAULT => 'TRUE'},
+ ],
+ },
+
+ setting_value => {
+ FIELDS => [
+ name => {TYPE => 'varchar(32)', NOTNULL => 1},
+ value => {TYPE => 'varchar(32)', NOTNULL => 1},
+ sortindex => {TYPE => 'INT2', NOTNULL => 1},
+ ],
+ INDEXES => [
+ setting_value_nv_unique_idx => {FIELDS => [qw(name value)],
+ TYPE => 'UNIQUE'},
+ setting_value_ns_unique_idx => {FIELDS => [qw(name sortindex)],
+ TYPE => 'UNIQUE'},
+ ],
+ },
+
+ profile_setting => {
+ FIELDS => [
+ user_id => {TYPE => 'INT3', NOTNULL => 1},
+ setting_name => {TYPE => 'varchar(32)', NOTNULL => 1},
+ setting_value => {TYPE => 'varchar(32)', NOTNULL => 1},
+ ],
+ INDEXES => [
+ profile_setting_value_unique_idx => {FIELDS => [qw(user_id setting_name)],
+ TYPE => 'UNIQUE'},
+ ],
+ },
+
};
#--------------------------------------------------------------------------
diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm
index e67a78c83..8045ee228 100644
--- a/Bugzilla/User.pm
+++ b/Bugzilla/User.pm
@@ -22,6 +22,7 @@
# Bradley Baetz <bbaetz@acm.org>
# Joel Peshkin <bugreport@peshkin.net>
# Byron Jones <bugzilla@glob.com.au>
+# Shane H. W. Travis <travis@sedsystems.ca>
# Max Kanat-Alexander <mkanat@kerio.com>
################################################################################
@@ -38,6 +39,7 @@ use Bugzilla::Config;
use Bugzilla::Error;
use Bugzilla::Util;
use Bugzilla::Constants;
+use Bugzilla::User::Setting;
use Bugzilla::Auth;
use base qw(Exporter);
@@ -224,6 +226,23 @@ sub queries {
return $self->{queries};
}
+sub settings {
+ my ($self) = @_;
+
+ return $self->{'settings'} if (defined $self->{'settings'});
+
+ # IF the user is logged in
+ # THEN get the user's settings
+ # ELSE get default settings
+ if ($self->id) {
+ $self->{'settings'} = get_all_settings($self->id);
+ } else {
+ $self->{'settings'} = get_defaults();
+ }
+
+ return $self->{'settings'};
+}
+
sub flush_queries_cache {
my $self = shift;
@@ -1148,6 +1167,20 @@ linkinfooter - Whether or not the query should be displayed in the footer.
Returns the disable text of the user, if any.
+=item C<settings>
+
+Returns a hash of hashes which holds the user's settings. The first key is
+the name of the setting, as found in setting.name. The second key is one of:
+is_enabled - true if the user is allowed to set the preference themselves;
+ false to force the site defaults
+ for themselves or must accept the global site default value
+default_value - the global site default for this setting
+value - the value of this setting for this user. Will be the same
+ as the default_value if the user is not logged in, or if
+ is_default is true.
+is_default - a boolean to indicate whether the user has chosen to make
+ a preference for themself or use the site default.
+
=item C<flush_queries_cache>
Some code modifies the set of stored queries. Because C<Bugzilla::User> does
diff --git a/Bugzilla/User/Setting.pm b/Bugzilla/User/Setting.pm
new file mode 100644
index 000000000..a8e1cbaed
--- /dev/null
+++ b/Bugzilla/User/Setting.pm
@@ -0,0 +1,352 @@
+# -*- 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.
+#
+# Contributor(s): Shane H. W. Travis <travis@sedsystems.ca>
+# Max Kanat-Alexander <mkanat@kerio.com>
+#
+
+
+package Bugzilla::User::Setting;
+
+use strict;
+use base qw(Exporter);
+
+# Module stuff
+@Bugzilla::User::Setting::EXPORT = qw(get_all_settings get_defaults
+ add_setting);
+
+use Bugzilla::Error;
+
+###############################
+### Module Initialization ###
+###############################
+
+sub new {
+ my $invocant = shift;
+ my $setting_name = shift;
+ my $user_id = shift;
+
+ my $class = ref($invocant) || $invocant;
+
+ # Create a ref to an empty hash and bless it
+ my $self = {};
+ bless($self, $class);
+
+ my $dbh = Bugzilla->dbh;
+
+ # Confirm that the $setting_name is properly formed;
+ # if not, throw a code error.
+ #
+ # NOTE: due to the way that setting names are used in templates,
+ # they must conform to to the limitations set for HTML NAMEs and IDs.
+ #
+ if ( !($setting_name =~ /^[a-zA-Z][-.:\w]*$/) ) {
+ ThrowCodeError("setting_name_invalid", { name => $setting_name });
+ }
+
+ # If there were only two parameters passed in, then we need
+ # to retrieve the information for this setting ourselves.
+ if (scalar @_ == 0) {
+
+ my ($default, $is_enabled, $value) =
+ $dbh->selectrow_array(
+ q{SELECT default_value, is_enabled, setting_value
+ FROM setting
+ LEFT JOIN profile_setting
+ ON setting.name = profile_setting.setting_name
+ WHERE name = ?
+ AND (profile_setting.user_id = ?
+ OR profile_setting.user_id IS NULL)},
+ undef,
+ $setting_name, $user_id);
+
+ $self->{'is_enabled'} = $is_enabled;
+ $self->{'default_value'} = $default;
+
+ # IF the setting is enabled, AND the user has chosen a setting
+ # THEN return that value
+ # ELSE return the site default, and note that it is the default.
+ if ( ($is_enabled) && (defined $value) ) {
+ $self->{'value'} = $value;
+ } else {
+ $self->{'value'} = $default;
+ $self->{'isdefault'} = 1;
+ }
+ }
+ else {
+ # If the values were passed in, simply assign them and return.
+ $self->{'is_enabled'} = shift;
+ $self->{'default_value'} = shift;
+ $self->{'value'} = shift;
+ $self->{'is_default'} = shift;
+ }
+
+ $self->{'_setting_name'} = $setting_name;
+ $self->{'_user_id'} = $user_id;
+
+ return $self;
+}
+
+###############################
+### Subroutine Definitions ###
+###############################
+
+sub add_setting {
+ my ($name, $values, $default_value) = @_;
+ my $dbh = Bugzilla->dbh;
+
+ return if _setting_exists($name);
+
+ ($name && $values && $default_value)
+ || ThrowCodeError("setting_info_invalid");
+
+ print "Adding a new user setting called '$name'\n";
+ $dbh->do(q{INSERT INTO setting (name, default_value, is_enabled)
+ VALUES (?, ?, 1)},
+ undef, ($name, $default_value));
+
+ my $sth = $dbh->prepare(q{INSERT INTO setting_value (name, value, sortindex)
+ VALUES (?, ?, ?)});
+
+ my @values_list = keys %{$values};
+ foreach my $key (@values_list){
+ $sth->execute($name, $key, $values->{$key});
+ }
+}
+
+sub get_all_settings {
+ my ($user_id) = @_;
+ my $settings;
+ my $dbh = Bugzilla->dbh;
+
+ my $sth = $dbh->prepare(
+ q{SELECT name, default_value, is_enabled, setting_value
+ FROM setting
+ LEFT JOIN profile_setting
+ ON setting.name = profile_setting.setting_name
+ WHERE profile_setting.user_id = ?
+ OR profile_setting.user_id IS NULL
+ ORDER BY name});
+
+ $sth->execute($user_id);
+ while (my ($name, $default_value, $is_enabled, $value)
+ = $sth->fetchrow_array()) {
+
+ my $is_default;
+
+ if ( ($is_enabled) && (defined $value) ) {
+ $is_default = 0;
+ } else {
+ $value = $default_value;
+ $is_default = 1;
+ }
+
+ $settings->{$name} = new Bugzilla::User::Setting(
+ $name, $user_id, $is_enabled,
+ $default_value, $value, $is_default);
+ }
+
+ return $settings;
+}
+
+sub get_defaults {
+ my $dbh = Bugzilla->dbh;
+ my $default_settings;
+
+ my $sth = $dbh->prepare(q{SELECT name, default_value, is_enabled
+ FROM setting
+ ORDER BY name});
+ $sth->execute();
+ while (my ($name, $default_value, $is_enabled) = $sth->fetchrow_array()) {
+
+ $default_settings->{$name} = new Bugzilla::User::Setting(
+ $name, 0, $is_enabled, $default_value, $default_value, 1);
+ }
+
+ return $default_settings;
+}
+
+sub set_default {
+ my ($setting_name, $default_value, $is_enabled) = @_;
+ my $dbh = Bugzilla->dbh;
+
+ my $sth = $dbh->prepare(q{UPDATE setting
+ SET default_value = ?, is_enabled = ?
+ WHERE name = ?});
+ $sth->execute($default_value, $is_enabled, $setting_name);
+}
+
+sub _setting_exists {
+ my ($setting_name) = @_;
+ my $dbh = Bugzilla->dbh;
+ my $sth = $dbh->prepare("SELECT name FROM setting WHERE name = ?");
+ $sth->execute($setting_name);
+ return ($sth->rows) ? 1 : 0;
+}
+
+
+sub legal_values {
+ my ($self) = @_;
+
+ return $self->{'legal_values'} if defined $self->{'legal_values'};
+
+ my $dbh = Bugzilla->dbh;
+ $self->{'legal_values'} = $dbh->selectcol_arrayref(
+ q{SELECT value
+ FROM setting_value
+ WHERE name = ?
+ ORDER BY sortindex},
+ undef, $self->{'_setting_name'});
+
+ return $self->{'legal_values'};
+}
+
+sub reset_to_default {
+ my ($self) = @_;
+
+ my $dbh = Bugzilla->dbh;
+ my $sth = $dbh->do(q{ DELETE
+ FROM profile_setting
+ WHERE setting_name = ?
+ AND user_id = ?},
+ undef, $self->{'_setting_name'}, $self->{'_user_id'});
+ $self->{'value'} = $self->{'default_value'};
+ $self->{'is_default'} = 1;
+}
+
+sub set {
+ my ($self, $value) = @_;
+ my $dbh = Bugzilla->dbh;
+ my $query;
+
+ if ($self->{'is_default'}) {
+ $query = q{INSERT INTO profile_setting
+ (setting_value, setting_name, user_id)
+ VALUES (?,?,?)};
+ } else {
+ $query = q{UPDATE profile_setting
+ SET setting_value = ?
+ WHERE setting_name = ?
+ AND user_id = ?};
+ }
+ $dbh->do($query, undef, $value, $self->{'_setting_name'}, $self->{'_user_id'});
+
+ $self->{'value'} = $value;
+ $self->{'is_default'} = 0;
+}
+
+
+
+1;
+
+__END__
+
+=head1 NAME
+Bugzilla::User::Setting - Object for a user preference setting
+
+=head1 SYNOPSIS
+Setting.pm creates a setting object, which is a hash containing the user
+preference information for a single preference for a single user. These
+are usually accessed through the "settings" object of a user, and not
+directly.
+
+=head1 DESCRIPTION
+use Bugzilla::User::Setting;
+my $settings;
+
+$settings->{$setting_name} = new Bugzilla::User::Setting(
+ $setting_name, $user_id);
+
+OR
+
+$settings->{$setting_name} = new Bugzilla::User::Setting(
+ $setting_name, $user_id, $is_enabled,
+ $default_value, $value, $is_default);
+
+=head1 CLASS FUNCTIONS
+
+=over 4
+
+=item C<add_setting($name, $values, $default_value)>
+
+Description: Checks for the existence of a setting, and adds it
+ to the database if it does not yet exist.
+Params: C<$name> - string - the name of the new setting
+ C<$values> - hash - contains the new values (key) and
+ sortindexes for the new setting
+ C<$default_value> - string - the site default
+Returns: a pointer to a hash of settings
+#
+#
+=item C<get_all_settings($user_id)>
+
+Description: Provides the user's choices for each setting in the
+ system; if the user has made no choice, uses the site
+ default instead.
+Params: C<$user_id> - integer - the user id.
+Returns: a pointer to a hash of settings
+
+=item C<get_defaults>
+
+Description: When a user is not logged in, they must use the site
+ defaults for every settings; this subroutine provides them.
+Params: none
+Returns: A pointer to a hash of settings
+
+=item C<set_default($setting_name, $default_value, $is_enabled)>
+
+Description: Sets the global default for a given setting. Also sets
+ whether users are allowed to choose their own value for
+ this setting, or if they must use the global default.
+Params: C<$setting_name> - string - the name of the setting
+ C<$default_value> - string - the new default value for this setting
+ C<$is_enabled> - boolean - if false, all users must use the global default
+Returns: nothing
+
+=begin private
+=item C<_setting_exists>
+
+Description: Determines if a given setting exists in the database.
+Params: C<$setting_name> - string - the setting name
+Returns: boolean - true if the setting already exists in the DB.
+
+=end private
+=head1 METHODS
+
+=over 4
+
+=item C<legal_values($setting_name)>
+
+Description: Returns all legal values for this setting
+Params: none
+Returns: A reference to an array containing all legal values
+
+=item C<reset_to_default>
+
+Description: If a user chooses to use the global default for a given
+ setting, their saved entry is removed from the database via
+ this subroutine.
+Params: none
+Returns: nothing
+
+=item C<set($value)>
+
+Description: If a user chooses to use their own value rather than the
+ global value for a given setting, OR changes their value for
+ a given setting, this subroutine is called to insert or
+ update the database as appropriate.
+Params: C<$value> - string - the new value for this setting for this user.
+Returns: nothing
+
+
diff --git a/checksetup.pl b/checksetup.pl
index 0dbf86bab..529b025b5 100755
--- a/checksetup.pl
+++ b/checksetup.pl
@@ -1479,6 +1479,10 @@ if ($^O !~ /MSWin32/i) {
require Bugzilla::Auth;
import Bugzilla::Auth 'bz_crypt';
+# This is done so we can add new settings as developers need them.
+require Bugzilla::User::Setting;
+import Bugzilla::User::Setting qw(add_setting);
+
# globals.pl clears the PATH, but File::Find uses Cwd::cwd() instead of
# Cwd::getcwd(), which we need to do because `pwd` isn't in the path - see
# http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2001-09/msg00115.html
diff --git a/editsettings.cgi b/editsettings.cgi
new file mode 100755
index 000000000..7ce05b2a2
--- /dev/null
+++ b/editsettings.cgi
@@ -0,0 +1,107 @@
+#!/usr/bin/perl -wT
+# -*- 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.
+#
+# Contributor(s): Shane H. W. Travis <travis@sedsystems.ca>
+#
+
+use strict;
+use lib qw(.);
+
+use Bugzilla;
+use Bugzilla::Constants;
+use Bugzilla::User::Setting;
+
+require "CGI.pl";
+
+# Use global template variables.
+use vars qw($template $vars);
+
+###############################
+### Subroutine Definitions ###
+###############################
+
+sub LoadSettings {
+
+ $vars->{'settings'} = Bugzilla::User::Setting::get_defaults();
+
+ my @setting_list = keys %{$vars->{'settings'}};
+ $vars->{'setting_names'} = \@setting_list;
+}
+
+sub SaveSettings{
+
+ my $cgi = Bugzilla->cgi;
+
+ $vars->{'settings'} = Bugzilla::User::Setting::get_defaults();
+ my @setting_list = keys %{$vars->{'settings'}};
+
+ foreach my $name (@setting_list) {
+ my $changed = 0;
+ my $old_enabled = $vars->{'settings'}->{$name}->{'is_enabled'};
+ my $old_value = $vars->{'settings'}->{$name}->{'default_value'};
+ my $enabled = defined $cgi->param("${name}-enabled") || 0;
+ my $value = $cgi->param("${name}");
+
+ # remove taint
+ if ($value =~ /^(\w+)$/ ) {
+ $value = $1;
+ }
+
+ if ( ($old_enabled != $enabled) ||
+ ($old_value ne $value) ) {
+ Bugzilla::User::Setting::set_default($name, $value, $enabled);
+ }
+ }
+}
+
+###################
+### Live code ###
+###################
+
+Bugzilla->login(LOGIN_REQUIRED);
+
+my $cgi = Bugzilla->cgi;
+print $cgi->header;
+
+UserInGroup("tweakparams")
+ || ThrowUserError("auth_failure", {group => "tweakparams",
+ action => "modify",
+ object => "settings"});
+
+my $action = trim($cgi->param('action') || 'load');
+
+if ($action eq 'update') {
+ SaveSettings();
+ $vars->{'changes_saved'} = 1;
+
+ $template->process("admin/settings/updated.html.tmpl", $vars)
+ || ThrowTemplateError($template->error());
+
+ exit;
+}
+
+if ($action eq 'load') {
+ LoadSettings();
+
+ $template->process("admin/settings/edit.html.tmpl", $vars)
+ || ThrowTemplateError($template->error());
+
+ exit;
+}
+
+#
+# No valid action found
+#
+ThrowUserError('no_valid_action', {'field' => "settings"});
diff --git a/template/en/default/account/prefs/prefs.html.tmpl b/template/en/default/account/prefs/prefs.html.tmpl
index 8d45e00b8..4973c807d 100644
--- a/template/en/default/account/prefs/prefs.html.tmpl
+++ b/template/en/default/account/prefs/prefs.html.tmpl
@@ -52,6 +52,8 @@
[% tabs = [ { name => "account", description => "Account settings",
saveable => "1" },
+ { name => "settings", description => "General Settings",
+ saveable => "1" },
{ name => "email", description => "Email settings",
saveable => "1" },
{ name => "saved-searches", description => "Saved searches",
diff --git a/template/en/default/account/prefs/settings.html.tmpl b/template/en/default/account/prefs/settings.html.tmpl
new file mode 100644
index 000000000..d116a291d
--- /dev/null
+++ b/template/en/default/account/prefs/settings.html.tmpl
@@ -0,0 +1,63 @@
+[%# 1.0@bugzilla.org %]
+[%# 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.
+ #
+ # Contributor(s): Shane H. W. Travis <travis@sedsystems.ca>
+ #
+ #%]
+
+[%# INTERFACE:
+ # setting_names: an array of strings
+ # settings: a hash of hashes, keyed by setting_name.
+ # Each hash contains:
+ # is_enabled - boolean
+ # default_value - string (global default for this setting)
+ # value - string (user-defined preference)
+ # is_default - boolean (true if user has no preference)
+ #%]
+
+[% PROCESS "global/setting-descs.none.tmpl" %]
+
+[% IF settings.size %]
+ <table border="0" cellpadding="8">
+ <tr>
+ [% FOREACH name = setting_names %]
+ [% IF settings.${name}.is_enabled %]
+ [% default_name = name _ '-isdefault' %]
+ [% default_val = settings.${name}.default_value %]
+ <tr>
+ <td align="right">
+ [% setting_descs.$name OR name FILTER html %]
+ </td>
+ <td>
+ <select name="[% name %]" id="[% name %]">
+ <option value="[% default_name %]"
+ [% ' selected="selected"' IF settings.${name}.is_default %]>
+ Site Default ([% setting_descs.${default_val} OR default_val FILTER html %])
+ </option>
+ [% FOREACH x = settings.${name}.legal_values %]
+ <option value="[% x FILTER html %]"
+ [% ' selected="selected"'
+ IF x == settings.${name}.value
+ AND NOT settings.${name}.is_default %]>
+ [% setting_descs.${x} OR x FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ [% END %]
+ [% END %]
+
+ </table>
+[% END %]
+<br>
diff --git a/template/en/default/admin/settings/edit.html.tmpl b/template/en/default/admin/settings/edit.html.tmpl
new file mode 100644
index 000000000..5a068e83b
--- /dev/null
+++ b/template/en/default/admin/settings/edit.html.tmpl
@@ -0,0 +1,102 @@
+[%# 1.0@bugzilla.org %]
+[%# 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.
+ #
+ # Contributor(s): Shane H. W. Travis <travis@sedsystems.ca>
+ #
+ #%]
+
+[%# INTERFACE:
+ # setting_names: an array of strings
+ # settings: a hash of hashes, keyed by setting_name.
+ # Each hash contains:
+ # is_enabled - boolean
+ # default_value - string (global default for this setting)
+ # value - string (user-defined preference)
+ # is_default - boolean (true if user has no preference)
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Edit Global Settings"
+ %]
+
+[% PROCESS "global/setting-descs.none.tmpl" %]
+
+<p>
+This lets you edit the global settings values.
+</p>
+<p>
+The Default Value displayed for each setting will apply to all users who
+do not choose their own value, and to anyone who is not logged in.
+</p>
+<p>
+The 'Enabled' checkbox controls whether or not this setting is available
+to users.<br>
+If it is checked, users will see this setting on their User Preferences page,
+and will be allowed to choose their own value if they desire.<br>
+If it is not checked, this setting will not apppear on the User Preference
+page, and the Default Value will automatically apply to everyone.
+</p>
+<hr>
+
+[% IF settings.size %]
+ <form name="adminsettingform" method="post" action="editsettings.cgi">
+ <table border="1" cellpadding="4">
+ <tr>
+ <th>Setting Text</th>
+ <th>Default Value</th>
+ <th>Enabled</th>
+ <tr>
+
+ [% FOREACH name = setting_names %]
+ [% checkbox_name = name _ '-enabled' %]
+ <tr>
+ <td align="right">
+ [% setting_descs.$name OR name FILTER html %]
+ </td>
+ <td>
+ <select name="[% name %]" id="[% name %]">
+ [% FOREACH x = settings.${name}.legal_values %]
+ <option value="[% x FILTER html %]"
+ [% " selected=\"selected\"" IF x == settings.${name}.default_value %]>
+ [% setting_descs.${x} OR x FILTER html %]
+ </option>
+ [% END %]
+ </select>
+ </td>
+ <td align="center">
+ <input type="checkbox"
+ name="[% checkbox_name %]"
+ id="[% checkbox_name %]"
+ [% " checked=\"checked\"" IF settings.${name}.is_enabled %]>
+ <br>
+ </td>
+ </tr>
+ [% END %]
+ </table>
+
+ <input type="hidden" name="action" value="update">
+ <table>
+ <tr>
+ <td width="150"></td>
+ <td>
+ <input type="submit" value="Submit Changes">
+ </td>
+ </tr>
+ </table>
+
+ </form>
+[% ELSE %]
+ There are no settings to edit.
+[% END %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/settings/updated.html.tmpl b/template/en/default/admin/settings/updated.html.tmpl
new file mode 100644
index 000000000..799fdde75
--- /dev/null
+++ b/template/en/default/admin/settings/updated.html.tmpl
@@ -0,0 +1,27 @@
+[%# 1.0@bugzilla.org %]
+[%# 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.
+ #
+ # Contributor(s): Shane H. W. Travis <travis@sedsystems.ca>
+ #
+ #%]
+
+[% PROCESS global/header.html.tmpl
+ title = "Settings Updated"
+ %]
+
+Your changes to the Global Settings have been saved.<br>
+<br>
+Return to the <a
+href="editsettings.cgi?action=load">Global Settings</a> page.
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl
index bcbbcc8a5..b7a3e0356 100644
--- a/template/en/default/filterexceptions.pl
+++ b/template/en/default/filterexceptions.pl
@@ -634,6 +634,11 @@
'deleted_bug_count'
],
+'admin/settings/edit.html.tmpl' => [
+ 'name',
+ 'checkbox_name'
+],
+
'account/login.html.tmpl' => [
'target',
],
@@ -656,4 +661,9 @@
'current_tab.description',
],
+'account/prefs/settings.html.tmpl' => [
+ 'name',
+ 'default_name'
+],
+
);
diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl
index cfc8229c8..5e75e1b30 100644
--- a/template/en/default/global/code-error.html.tmpl
+++ b/template/en/default/global/code-error.html.tmpl
@@ -216,6 +216,15 @@
[%+ ELSIF fld == "z" %]the multiple tables/images
[%+ ELSE %]a report axis[% END %] field.
+ [% ELSIF error == "setting_info_invalid" %]
+ To create a new setting, you must supply a setting name, a list of
+ value/sortindex pairs, and the devault value.
+
+ [% ELSIF error == "setting_name_invalid" %]
+ The setting name <em>[% name FILTER html %]</em> is not a valid
+ option. Setting names must begin with a letter, and contain only
+ letters, digits, or the symbols '_', '-', '.', or ':'.
+
[% ELSIF error == "token_generation_error" %]
Something is seriously wrong with the token generation system.
diff --git a/template/en/default/global/field-descs.none.tmpl b/template/en/default/global/field-descs.none.tmpl
index 1b410d1f2..8997bfa0d 100644
--- a/template/en/default/global/field-descs.none.tmpl
+++ b/template/en/default/global/field-descs.none.tmpl
@@ -59,6 +59,8 @@
"reporter" => "Reporter",
"reporter_accessible" => "Reporter accessible?",
"resolution" => "Resolution",
+ "setting" => "Setting",
+ "settings" => "Settings",
"short_desc" => "Summary",
"status_whiteboard" => "Whiteboard",
"target_milestone" => "Target Milestone",
diff --git a/template/en/default/global/setting-descs.none.tmpl b/template/en/default/global/setting-descs.none.tmpl
new file mode 100644
index 000000000..26bed57a7
--- /dev/null
+++ b/template/en/default/global/setting-descs.none.tmpl
@@ -0,0 +1,26 @@
+[%# 1.0@bugzilla.org %]
+[%# 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.
+ #
+ # Contributor(s): Shane H. W. Travis <travis@sedsystems.ca>
+ #
+ #%]
+
+[%# Remember to PROCESS rather than INCLUDE this template. %]
+
+[% PROCESS global/variables.none.tmpl %]
+
+[% setting_descs = {
+ "off" => "Off",
+ "on" => "On"
+ }
+%]
diff --git a/template/en/default/global/useful-links.html.tmpl b/template/en/default/global/useful-links.html.tmpl
index eb8c7e24c..6d45bfd1b 100644
--- a/template/en/default/global/useful-links.html.tmpl
+++ b/template/en/default/global/useful-links.html.tmpl
@@ -74,7 +74,8 @@
<div class="links">
<a href="userprefs.cgi">Prefs</a>
- [% ' | <a href="editparams.cgi">Parameters</a>'
+ [% ' | <a href="editparams.cgi">Parameters</a> ' _
+ ' | <a href="editsettings.cgi">User Settings</a>'
IF user.groups.tweakparams %]
[% ' | <a href="editusers.cgi">Users</a>' IF user.groups.editusers
|| user.can_bless %]
diff --git a/userprefs.cgi b/userprefs.cgi
index 342df065b..3331d5b91 100755
--- a/userprefs.cgi
+++ b/userprefs.cgi
@@ -20,6 +20,7 @@
# Christopher Aillon <christopher@aillon.com>
# Gervase Markham <gerv@gerv.net>
# Vlad Dascalu <jocuri@softhome.net>
+# Shane H. W. Travis <travis@sedsystems.ca>
use strict;
@@ -139,6 +140,39 @@ sub SaveAccount {
}
+sub DoSettings {
+ $vars->{'settings'} = Bugzilla->user->settings;
+
+ my @setting_list = keys %{Bugzilla->user->settings};
+ $vars->{'setting_names'} = \@setting_list;
+}
+
+sub SaveSettings {
+ my $cgi = Bugzilla->cgi;
+
+ my $settings = Bugzilla->user->settings;
+ my @setting_list = keys %{Bugzilla->user->settings};
+
+ foreach my $name (@setting_list) {
+ next if ! ($settings->{$name}->{'is_enabled'});
+ my $value = $cgi->param($name);
+
+ # de-taint the value.
+ if ($value =~ /^([-\w]+)$/ ) {
+ $value = $1;
+ }
+ if ($value eq "${name}-isdefault" ) {
+ if (! $settings->{$name}->{'is_default'}) {
+ $settings->{$name}->reset_to_default;
+ }
+ }
+ else {
+ $settings->{$name}->set($value);
+ }
+ }
+ $vars->{'settings'} = Bugzilla->user->settings(1);
+}
+
sub DoEmail {
my $dbh = Bugzilla->dbh;
@@ -367,6 +401,11 @@ SWITCH: for ($current_tab_name) {
DoAccount();
last SWITCH;
};
+ /^settings$/ && do {
+ SaveSettings() if $cgi->param('dosave');
+ DoSettings();
+ last SWITCH;
+ };
/^email$/ && do {
SaveEmail() if $cgi->param('dosave');
DoEmail();