]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 98123 : Create a user preferences infrastructure (became 'General Settings')
authortravis%sedsystems.ca <>
Thu, 10 Mar 2005 23:51:40 +0000 (23:51 +0000)
committertravis%sedsystems.ca <>
Thu, 10 Mar 2005 23:51:40 +0000 (23:51 +0000)
Patch by Shane H. W. Travis <travis@sedsystems.ca>   r=jouni, mkanat  a=myk

15 files changed:
Bugzilla/DB/Schema.pm
Bugzilla/User.pm
Bugzilla/User/Setting.pm [new file with mode: 0644]
checksetup.pl
editsettings.cgi [new file with mode: 0755]
template/en/default/account/prefs/prefs.html.tmpl
template/en/default/account/prefs/settings.html.tmpl [new file with mode: 0644]
template/en/default/admin/settings/edit.html.tmpl [new file with mode: 0644]
template/en/default/admin/settings/updated.html.tmpl [new file with mode: 0644]
template/en/default/filterexceptions.pl
template/en/default/global/code-error.html.tmpl
template/en/default/global/field-descs.none.tmpl
template/en/default/global/setting-descs.none.tmpl [new file with mode: 0644]
template/en/default/global/useful-links.html.tmpl
userprefs.cgi

index 3a15a755ed21ca09a870a95aa2578b2360dc72e3..99f5f106fd8bb185d33d3e55e2f9874792989782 100644 (file)
@@ -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'},
+        ],
+     },
+
 };
 #--------------------------------------------------------------------------
 
index e67a78c831ba6bb7061c3b0676e6204eaeb34bcd..8045ee228a54f88271f72b7d0396db6aaf52d805 100644 (file)
@@ -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 (file)
index 0000000..a8e1cba
--- /dev/null
@@ -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
+
+
index 0dbf86bab457d69a1cd56be57db1f0fb0fa5dfe2..529b025b51d110897b27983cddf2d9852843b870 100755 (executable)
@@ -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 (executable)
index 0000000..7ce05b2
--- /dev/null
@@ -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"});
index 8d45e00b83fe993e220521e4de954b878b01b545..4973c807dd7f5fe18358560aa32831af95a9c3bc 100644 (file)
@@ -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 (file)
index 0000000..d116a29
--- /dev/null
@@ -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 (file)
index 0000000..5a068e8
--- /dev/null
@@ -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 (file)
index 0000000..799fdde
--- /dev/null
@@ -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 %]
index bcbbcc8a5d89da184bca5974be3c1d3474fa52fc..b7a3e03565a242f83a536100c298399beb2c173a 100644 (file)
   'deleted_bug_count'
 ],
 
+'admin/settings/edit.html.tmpl' => [
+  'name',
+  'checkbox_name'
+],
+
 'account/login.html.tmpl' => [
   'target', 
 ],
   'current_tab.description', 
 ],
 
+'account/prefs/settings.html.tmpl' => [
+  'name',
+  'default_name'
+],
+
 );
index cfc8229c8cc4b79001af04c42c3e137e149588b5..5e75e1b302873090a3a7de62a63c6c0f6542bace 100644 (file)
     [%+ 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.
 
index 1b410d1f2feebc1bd45b8d5254a1b32b90ed97db..8997bfa0d3d3c687ba3e34e6bb40f7777ec5083e 100644 (file)
@@ -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 (file)
index 0000000..26bed57
--- /dev/null
@@ -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"
+                   } 
+%]
index eb8c7e24c06898974c7ac87909edc8c8621ecd8d..6d45bfd1b7f36c509b1668e227a49972fec4cd37 100644 (file)
@@ -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 %]
index 342df065ba759532151049663713f6f168822684..3331d5b91aa59c6fb7f8241bf6fa0c2a64b450bb 100755 (executable)
@@ -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();