summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xeditvalues.cgi386
-rw-r--r--template/en/default/admin/fieldvalues/confirm-delete.html.tmpl108
-rw-r--r--template/en/default/admin/fieldvalues/create.html.tmpl54
-rw-r--r--template/en/default/admin/fieldvalues/created.html.tmpl39
-rw-r--r--template/en/default/admin/fieldvalues/deleted.html.tmpl38
-rw-r--r--template/en/default/admin/fieldvalues/edit.html.tmpl60
-rw-r--r--template/en/default/admin/fieldvalues/footer.html.tmpl56
-rw-r--r--template/en/default/admin/fieldvalues/list.html.tmpl73
-rw-r--r--template/en/default/admin/fieldvalues/select-field.html.tmpl50
-rw-r--r--template/en/default/admin/fieldvalues/updated.html.tmpl51
-rw-r--r--template/en/default/admin/table.html.tmpl15
-rw-r--r--template/en/default/global/useful-links.html.tmpl14
-rw-r--r--template/en/default/global/user-error.html.tmpl43
13 files changed, 976 insertions, 11 deletions
diff --git a/editvalues.cgi b/editvalues.cgi
new file mode 100755
index 000000000..8231dab5b
--- /dev/null
+++ b/editvalues.cgi
@@ -0,0 +1,386 @@
+#!/usr/bin/perl -wT
+# 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): Max Kanat-Alexander <mkanat@kerio.com>
+
+# This is a script to edit the values of fields that have drop-down
+# or select boxes. It is largely a copy of editmilestones.cgi, but
+# with some cleanup.
+
+use strict;
+use lib ".";
+
+use Bugzilla;
+use Bugzilla::Util;
+use Bugzilla::Error;
+use Bugzilla::Constants;
+use Bugzilla::Config qw(:DEFAULT :locations);
+
+# List of different tables that contain the changeable field values
+# (the old "enums.") Keep them in alphabetical order by their
+# English name from field-descs.html.tmpl.
+# Format: Array of valid field names.
+# Admins may add resolution and bug_status to this list, but they
+# do so at their own risk.
+our @valid_fields = ('op_sys', 'rep_platform', 'priority', 'bug_severity',);
+
+######################################################################
+# Subroutines
+######################################################################
+
+# Returns whether or not the specified table exists in the @tables array.
+sub FieldExists ($) {
+ my ($field) = @_;
+
+ return lsearch(\@valid_fields, $field) >= 0;
+}
+
+# Same as FieldExists, but emits and error and dies if it fails.
+sub FieldMustExist ($) {
+ my ($field)= @_;
+
+ $field ||
+ ThrowUserError('fieldname_not_specified');
+
+ # Is it a valid field to be editing?
+ FieldExists($field) ||
+ ThrowUserError('fieldname_invalid', {'field' => $field});
+}
+
+# Returns if the specified value exists for the field specified.
+sub ValueExists ($$) {
+ my ($field, $value) = @_;
+ FieldMustExist($field);
+ trick_taint($field);
+ # Value is safe because it's being passed only to a SELECT
+ # statement via a placeholder.
+ trick_taint($value);
+
+ my $dbh = Bugzilla->dbh;
+ my $value_count =
+ $dbh->selectrow_array("SELECT COUNT(*) FROM $field "
+ . " WHERE value = ?", undef, $value);
+
+ return $value_count;
+}
+
+# Same check as ValueExists, emits an error text and dies if it fails.
+sub ValueMustExist ($$) {
+ my ($field, $value)= @_;
+
+ # Values may not be empty (it's very difficult to deal
+ # with empty values in the admin interface).
+ trim($value) || ThrowUserError('fieldvalue_not_specified');
+
+ # Does it exist in the DB?
+ ValueExists($field, $value) ||
+ ThrowUserError('fieldvalue_doesnt_exist', {'value' => $value,
+ 'field' => $field});
+}
+
+######################################################################
+# Main Body Execution
+######################################################################
+
+# require the user to have logged in
+Bugzilla->login(LOGIN_REQUIRED);
+
+my $dbh = Bugzilla->dbh;
+my $cgi = Bugzilla->cgi;
+my $template = Bugzilla->template;
+my $vars = {};
+
+print $cgi->header();
+
+exists Bugzilla->user->groups->{'editcomponents'} ||
+ ThrowUserError('auth_failure', {group => "editcomponents",
+ action => "edit",
+ object => "field values"});
+
+#
+# often-used variables
+#
+my $field = trim($cgi->param('field') || '');
+my $value = trim($cgi->param('value') || '');
+my $sortkey = trim($cgi->param('sortkey') || '0');
+my $action = trim($cgi->param('action') || '');
+
+
+#
+# field = '' -> Show nice list of fields
+#
+unless ($field) {
+ # Convert @valid_fields into the format that select-field wants.
+ my @field_list = ();
+ foreach my $field_name (@valid_fields) {
+ push(@field_list, {name => $field_name});
+ }
+
+ $vars->{'fields'} = \@field_list;
+ $template->process("admin/fieldvalues/select-field.html.tmpl",
+ $vars)
+ || ThrowTemplateError($template->error());
+ exit;
+}
+
+
+#
+# action='' -> Show nice list of values.
+#
+unless ($action) {
+ FieldMustExist($field);
+ # Now we know the $field is valid.
+ trick_taint($field);
+
+ my $fieldvalues =
+ $dbh->selectall_arrayref("SELECT value AS name, sortkey"
+ . " FROM $field ORDER BY sortkey, value",
+ {Slice =>{}});
+ $vars->{'field'} = $field;
+ $vars->{'values'} = $fieldvalues;
+ $template->process("admin/fieldvalues/list.html.tmpl",
+ $vars)
+ || ThrowTemplateError($template->error());
+
+ exit;
+}
+
+
+#
+# action='add' -> show form for adding new field value.
+# (next action will be 'new')
+#
+if ($action eq 'add') {
+ FieldMustExist($field);
+
+ $vars->{'value'} = $value;
+ $vars->{'field'} = $field;
+ $template->process("admin/fieldvalues/create.html.tmpl",
+ $vars)
+ || ThrowTemplateError($template->error());
+
+ exit;
+}
+
+
+#
+# action='new' -> add field value entered in the 'action=add' screen
+#
+if ($action eq 'new') {
+ FieldMustExist($field);
+ trick_taint($field);
+
+ # Cleanups and validity checks
+ $value || ThrowUserError('fieldvalue_undefined');
+
+ if (length($value) > 60) {
+ ThrowUserError('fieldvalue_name_too_long',
+ {'value' => $value});
+ }
+ # Need to store in case detaint_natural() clears the sortkey
+ my $stored_sortkey = $sortkey;
+ if (!detaint_natural($sortkey)) {
+ ThrowUserError('fieldvalue_sortkey_invalid',
+ {'name' => $field,
+ 'sortkey' => $stored_sortkey});
+ }
+ if (ValueExists($field, $value)) {
+ ThrowUserError('fieldvalue_already_exists',
+ {'field' => $field,
+ 'value' => $value});
+ }
+ # Value is only used in a SELECT placeholder and through the HTML filter.
+ trick_taint($value);
+
+ # Add the new field value.
+ my $sth = $dbh->prepare("INSERT INTO $field ( value, sortkey )
+ VALUES ( ?, ? )");
+ $sth->execute($value, $sortkey);
+
+ unlink "$datadir/versioncache";
+
+ $vars->{'value'} = $value;
+ $vars->{'field'} = $field;
+ $template->process("admin/fieldvalues/created.html.tmpl",
+ $vars)
+ || ThrowTemplateError($template->error());
+
+ exit;
+}
+
+
+#
+# action='del' -> ask if user really wants to delete
+# (next action would be 'delete')
+#
+if ($action eq 'del') {
+ ValueMustExist($field, $value);
+ trick_taint($field);
+ trick_taint($value);
+
+ # See if any bugs are still using this value.
+ $vars->{'bug_count'} =
+ $dbh->selectrow_array("SELECT COUNT(*) FROM bugs WHERE $field = ?",
+ undef, $value) || 0;
+ $vars->{'value_count'} =
+ $dbh->selectrow_array("SELECT COUNT(*) FROM $field");
+
+ $vars->{'value'} = $value;
+ $vars->{'field'} = $field;
+ $template->process("admin/fieldvalues/confirm-delete.html.tmpl",
+ $vars)
+ || ThrowTemplateError($template->error());
+
+ exit;
+}
+
+
+#
+# action='delete' -> really delete the field value
+#
+if ($action eq 'delete') {
+ ValueMustExist($field, $value);
+ trick_taint($field);
+ trick_taint($value);
+
+ # Check if there are any bugs that still have this value.
+ my $bug_ids = $dbh->selectcol_arrayref(
+ "SELECT bug_id FROM bugs WHERE $field = ?", undef, $value);
+
+ if (scalar(@$bug_ids)) {
+ # You tried to delete a field that bugs are still using.
+ # You can't just delete the bugs. That's ridiculous.
+ $dbh->do('UNLOCK TABLES');
+ ThrowUserError("fieldvalue_still_has_bugs",
+ { field => $field, value => $value,
+ count => scalar(@$bug_ids) });
+ }
+
+ $dbh->do("DELETE FROM $field WHERE value = ?", undef, $value);
+
+ unlink "$datadir/versioncache";
+
+ $vars->{'value'} = $value;
+ $vars->{'field'} = $field;
+ $template->process("admin/fieldvalues/deleted.html.tmpl",
+ $vars)
+ || ThrowTemplateError($template->error());
+ exit;
+}
+
+
+#
+# action='edit' -> present the edit-value form
+# (next action would be 'update')
+#
+if ($action eq 'edit') {
+ ValueMustExist($field, $value);
+ trick_taint($field);
+ trick_taint($value);
+
+ $vars->{'sortkey'} = $dbh->selectrow_array(
+ "SELECT sortkey FROM $field WHERE value = ?", undef, $value) || 0;
+
+ $vars->{'value'} = $value;
+ $vars->{'field'} = $field;
+
+ $template->process("admin/fieldvalues/edit.html.tmpl",
+ $vars)
+ || ThrowTemplateError($template->error());
+
+ exit;
+}
+
+
+#
+# action='update' -> update the field value
+#
+if ($action eq 'update') {
+ my $valueold = trim($cgi->param('valueold') || '');
+ my $sortkeyold = trim($cgi->param('sortkeyold') || '0');
+
+ ValueMustExist($field, $valueold);
+ trick_taint($field);
+ trick_taint($valueold);
+
+ if (length($value) > 60) {
+ ThrowUserError('fieldvalue_name_too_long',
+ {'value' => $value});
+ }
+
+ $dbh->do("LOCK TABLES bugs WRITE, $field WRITE");
+
+ # Need to store because detaint_natural() will delete this if
+ # invalid
+ my $stored_sortkey = $sortkey;
+ if ($sortkey != $sortkeyold) {
+
+ if (!detaint_natural($sortkey)) {
+ $dbh->do('UNLOCK TABLES');
+ ThrowUserError('fieldvalue_sortkey_invalid',
+ {'name' => $field,
+ 'sortkey' => $stored_sortkey});
+
+ }
+
+ $dbh->do("UPDATE $field SET sortkey = ? WHERE value = ?",
+ undef, $sortkey, $valueold);
+
+ unlink "$datadir/versioncache";
+ $vars->{'updated_sortkey'} = 1;
+ $vars->{'sortkey'} = $sortkey;
+ }
+
+ if ($value ne $valueold) {
+
+ unless ($value) {
+ $dbh->do('UNLOCK TABLES');
+ ThrowUserError('fieldvalue_undefined');
+ }
+ if (ValueExists($field, $value)) {
+ $dbh->do('UNLOCK TABLES');
+ ThrowUserError('fieldvalue_already_exists',
+ {'value' => $value,
+ 'field' => $field});
+ }
+ trick_taint($value);
+
+ $dbh->do("UPDATE bugs SET $field = ?, delta_ts = NOW()
+ WHERE $field = ?", undef, $value, $valueold);
+
+ $dbh->do("UPDATE $field SET value = ? WHERE value = ?",
+ undef, $value, $valueold);
+
+ unlink "$datadir/versioncache";
+
+ $vars->{'updated_value'} = 1;
+ }
+
+ $dbh->do('UNLOCK TABLES');
+
+ $vars->{'value'} = $value;
+ $vars->{'field'} = $field;
+ $template->process("admin/fieldvalues/updated.html.tmpl",
+ $vars)
+ || ThrowTemplateError($template->error());
+
+ exit;
+}
+
+
+#
+# No valid action found
+#
+# We can't get here without $field being defined --
+# See the unless($field) block at the top.
+ThrowUserError('no_valid_action', { field => $field } );
diff --git a/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl b/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl
new file mode 100644
index 000000000..234a895a7
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl
@@ -0,0 +1,108 @@
+[%# 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): Max Kanat-Alexander <mkanat@kerio.com>
+ #%]
+
+[%# INTERFACE:
+ # value: string; The field value being deleted.
+ # bug_count: number; The number of bugs that have this field value.
+ # value_count: number; The number of values left for this field, including
+ # this value.
+ # field: string; The name of the field.
+ #%]
+
+[% title = BLOCK %]Delete Value '[% value FILTER html %]' from the
+ '[% field FILTER html %]' field[% END %]
+
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+<table border="1" cellpadding="4" cellspacing="0">
+<tr bgcolor="#6666FF">
+ <th valign="top" align="left">Field</th>
+ <th valign="top" align="left">Value</th>
+</tr>
+<tr>
+ <td valign="top">Field Name:</td>
+ <td valign="top">[% field FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">Field Value:</td>
+ <td valign="top">[% value FILTER html %]</td>
+</tr>
+<tr>
+ <td valign="top">[% terms.Bugs %]:</td>
+ <td valign="top">
+[% IF bug_count %]
+ <a title="List of [% terms.bugs %] where '[% field FILTER html %]' is '
+ [% value FILTER html %]'"
+ href="buglist.cgi?[% field FILTER url_quote %]=[%- value FILTER url_quote %]">[% bug_count FILTER html %]</a>
+[% ELSE %]
+ None
+[% END %]
+ </td>
+</tr>
+</table>
+
+<h2>Confirmation</h2>
+
+[% IF bug_count %]
+
+ Sorry, there
+
+ [% IF bug_count > 1 %]
+ are [% bug_count FILTER html %] [%+ terms.bugs %]
+ [% ELSE %]
+ is [% bug_count FILTER html %] [%+ terms.bug %]
+ [% END %]
+
+ that still have this field value. You must change the field value on
+ <a title="List of [% terms.bugs %] where '[% field FILTER html %]' is '[% value FILTER html %]'"
+ href="buglist.cgi?[% field FILTER url_quote %]=[%- value FILTER url_quote %]">
+ [% IF bug_count > 1 %]
+ those [% terms.bugs %]
+ [% ELSE %]
+ that [% terms.bug %]
+ [% END %]
+ </a>
+ to another value before you can delete this value.
+
+[% END %]
+
+[% IF value_count == 1 %]
+
+ <p>Sorry, but '[% value FILTER html %]' is the last value for
+ '[%- field FILTER html %]', and so it can not be deleted.</p>
+
+ [% ELSE %]
+
+ [% IF bug_count == 0 %]
+
+ <p>Do you really want to delete this value?<p>
+
+ <form method="post" action="editvalues.cgi">
+ <input type="submit" value="Yes, delete">
+ <input type="hidden" name="action" value="delete">
+ <input type="hidden" name="field" value="[% field FILTER html %]">
+ <input type="hidden" name="value" value="[% value FILTER html %]">
+ </form>
+
+ [% END %]
+
+[% END %]
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/create.html.tmpl b/template/en/default/admin/fieldvalues/create.html.tmpl
new file mode 100644
index 000000000..70dbc4eb7
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/create.html.tmpl
@@ -0,0 +1,54 @@
+[%# 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): Max Kanat-Alexander <mkanat@kerio.com>
+ #%]
+
+[%# INTERFACE:
+ # field: string; name of the field the value is being created for
+ #%]
+
+[% title = BLOCK %]Add Value for the '[% field FILTER html %]' field[% END %]
+[% h2 = BLOCK %]This page allows you to add a new value for the
+ '[% field FILTER html %]' field.[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+ h2 = h2
+%]
+
+<form method="post" action="editvalues.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+ <tr>
+ <th align="right"><label for="value">Value:</label></th>
+ <td><input id="value" size="30" maxlength="60" name="value"
+ value=""></td>
+ </tr>
+ <tr>
+ <th align="right"><label for="sortkey">Sortkey:</label></th>
+ <td><input id="sortkey" size="10" maxlength="20" name="sortkey"
+ value=""></td>
+ </tr>
+ </table>
+ <input type="submit" value="Add">
+ <input type="hidden" name="action" value="new">
+ <input type="hidden" name='field' value="[% field FILTER html %]">
+
+</form>
+
+<p>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_add_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/created.html.tmpl b/template/en/default/admin/fieldvalues/created.html.tmpl
new file mode 100644
index 000000000..28688d991
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/created.html.tmpl
@@ -0,0 +1,39 @@
+[%# 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): Max Kanat-Alexander <mkanat@kerio.com>
+ #%]
+
+[%# INTERFACE:
+ # value: string; the name of the newly created field value
+ # field: string; the name of the field the value belongs to
+ #%]
+
+[% title = BLOCK %]New Value '[% product FILTER html %]' added to
+ '[% field FILTER html %]' field[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+<p>The value '<a title="Edit value '[% value FILTER html %]' of
+ for the '[% field FILTER html %]' field"
+ href="editvalues.cgi?action=edit&amp;field=
+ [%- field FILTER url_quote %]&amp;value=[% value FILTER url_quote %]">
+ [%- value FILTER html %]</a>' has been added as a valid choice for
+ the '[% field FILTER html %]' field.</p>
+
+<p>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/deleted.html.tmpl b/template/en/default/admin/fieldvalues/deleted.html.tmpl
new file mode 100644
index 000000000..2bb3c840b
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/deleted.html.tmpl
@@ -0,0 +1,38 @@
+[%# 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): Max Kanat-Alexander <mkanat@kerio.com>
+ #%]
+
+[%# INTERFACE:
+ # value: string; the field value that was deleted.
+ #
+ # field: string; the field the value was deleted from.
+ #
+ #%]
+
+[% title = BLOCK %]Deleted Value '[% value FILTER html %]' for the
+ '[% field FILTER html %]' Field[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+<p>Field Value '[% value FILTER html %]' deleted.</p>
+
+<p>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_edit_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/edit.html.tmpl b/template/en/default/admin/fieldvalues/edit.html.tmpl
new file mode 100644
index 000000000..9771148cc
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/edit.html.tmpl
@@ -0,0 +1,60 @@
+[%# 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): Max Kanat-Alexander <mkanat@kerio.com>
+ #%]
+
+[%# INTERFACE:
+ # value: string; The field value we are editing.
+ # sortkey: number; Sortkey of the field value we are editing.
+ # field: string; The field this value belongs to.
+ #%]
+
+[% PROCESS global/variables.none.tmpl %]
+
+[% title = BLOCK %]Edit Value '[% value FILTER html %]' '
+ [%- filter FILTER html %]'[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+<form method="post" action="editvalues.cgi">
+ <table border="0" cellpadding="4" cellspacing="0">
+
+ <tr>
+ <th valign="top"><label for="value">Field Value:</label></th>
+ <td><input id="value" size="20" maxlength="60" name="value" value="
+ [%- value FILTER html %]"></td>
+ </tr>
+ <tr>
+ <th align="right"><label for="sortkey">Sortkey:</label></th>
+ <td><input id="sortkey" size="20" maxlength="20" name="sortkey" value="
+ [%- sortkey FILTER html %]"></td>
+ </tr>
+
+ </table>
+
+ <input type="hidden" name="valueold" value="[% value FILTER html %]">
+ <input type="hidden" name="sortkeyold" value="[% sortkey FILTER html %]">
+ <input type="hidden" name="action" value="update">
+ <input type="hidden" name="field" value="[% field FILTER html %]">
+ <input type="submit" value="Update">
+
+</form>
+
+<p>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_edit_link = 1 %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/footer.html.tmpl b/template/en/default/admin/fieldvalues/footer.html.tmpl
new file mode 100644
index 000000000..05e8c757b
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/footer.html.tmpl
@@ -0,0 +1,56 @@
+[%# 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): Max Kanat-Alexander <mkanat@kerio.com>
+ #%]
+
+[%# INTERFACE:
+ # value: string; the value being inserted/edited.
+ # field: string; the name of the field which the value
+ # belongs/belonged to
+ #
+ # no_XXX_link: boolean; if defined, then don't show the corresponding
+ # link. Supported parameters are:
+ #
+ # no_edit_link
+ # no_edit_other_link
+ # no_add_link
+ #%]
+
+<p>
+
+<hr>
+
+[% UNLESS no_add_link %]
+ <a title="Add a value for the '[% field FILTER html %]' field."
+ href="editvalues.cgi?action=add&amp;field=
+ [%- field FILTER url_quote %]">Add</a> a value.
+[% END %]
+
+[% IF value && !no_edit_milestone_link %]
+ Edit value <a
+ title="Edit value '[% value FILTER html %]' for the '
+ [%- field FILTER html %]' field"
+ href="editvalues.cgi?action=edit&amp;field=
+ [%- field FILTER url_quote %]&amp;value=[% value FILTER url_quote %]">
+ '[% value FILTER html %]'</a>.
+[% END %]
+
+[% UNLESS no_edit_other_link %]
+ Edit other values for the <a
+ href="editvalues.cgi?field=
+ [%- field FILTER url_quote %]">'[% field FILTER html %]'</a> field.
+
+[% END %]
+
+</p>
diff --git a/template/en/default/admin/fieldvalues/list.html.tmpl b/template/en/default/admin/fieldvalues/list.html.tmpl
new file mode 100644
index 000000000..4f686d338
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/list.html.tmpl
@@ -0,0 +1,73 @@
+[%# 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): Max Kanat-Alexander <mkanat@kerio.com>
+ #%]
+
+[%# INTERFACE:
+ # values: array of hashes having the following properties:
+ # - name: string; The value.
+ # - sortkey: number; The sortkey used to order the value when
+ # displayed to the user in a list.
+ #
+ # field: string; the name of the field we are editing values for.
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% PROCESS global/variables.none.tmpl %]
+
+[% title = BLOCK %]Select value for the
+ '[% field FILTER html %]' field[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+[% edit_contentlink = BLOCK %]editvalues.cgi?action=edit&amp;field=
+ [%- field FILTER url_quote %]&amp;value=%%name%%[% END %]
+[% delete_contentlink = BLOCK %]editvalues.cgi?action=del&amp;field=
+ [%- field FILTER url_quote %]&amp;value=%%name%%[% END %]
+
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit field value..."
+ contentlink => edit_contentlink
+ },
+ {
+ name => "sortkey"
+ heading => "Sortkey"
+ },
+ ]
+%]
+
+[% columns.push({
+ heading => "Action"
+ content => "Delete"
+ contentlink => delete_contentlink
+ }) %]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = values
+%]
+
+<p>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl
+ no_edit_other_link = 1
+ %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/select-field.html.tmpl b/template/en/default/admin/fieldvalues/select-field.html.tmpl
new file mode 100644
index 000000000..834295225
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/select-field.html.tmpl
@@ -0,0 +1,50 @@
+[%# 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): Max Kanat-Alexander <mkanat@kerio.com>
+ #
+ #%]
+
+[%# INTERFACE:
+ # fields: Array of hashes. Each hash contains only one key, "name."
+ # The names are the same as the keys from field_descs
+ # (see global/field-descs.html.tmpl).
+ #%]
+
+[% USE Bugzilla %]
+[% cgi = Bugzilla.cgi %]
+
+[% PROCESS global/variables.none.tmpl %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Edit values for which field?"
+%]
+
+[% columns = [
+ {
+ name => "name"
+ heading => "Edit field values for..."
+ content_use_field = 1
+ contentlink => "editvalues.cgi?field=%%name%%"
+ }
+ ]
+%]
+
+[% PROCESS admin/table.html.tmpl
+ columns = columns
+ data = fields
+%]
+
+<p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/fieldvalues/updated.html.tmpl b/template/en/default/admin/fieldvalues/updated.html.tmpl
new file mode 100644
index 000000000..c19aac285
--- /dev/null
+++ b/template/en/default/admin/fieldvalues/updated.html.tmpl
@@ -0,0 +1,51 @@
+[%# 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): Max Kanat-Alexander <mkanat@kerio.com>
+ #%]
+
+[%# INTERFACE:
+ #
+ # 'updated_XXX' variables are booleans, and are defined if the
+ # 'XXX' field was updated during the edit just being handled.
+ # Variables called just 'XXX' are strings, and are the _new_ contents
+ # of the fields.
+ #
+ # value & updated_value: the name of the field value
+ # sortkey & updated_sortkey: the field value sortkey
+ # field: string; the field that the value belongs to
+ #%]
+
+[% title = BLOCK %]Updating Value '[% value FILTER html %]' of the
+ '[% field FILTER html %]' Field[% END %]
+[% PROCESS global/header.html.tmpl
+ title = title
+%]
+
+[% IF updated_value %]
+ <p>Updated field value to: '[% value FILTER html %]'.</p>
+[% END %]
+
+[% IF updated_sortkey %]
+ <p>Updated field value sortkey to: '[% sortkey FILTER html %]'.</p>
+[% END %]
+
+[% UNLESS (updated_sortkey || updated_value) %]
+ <p>Nothing changed for field value '[% value FILTER html %]'.
+[% END %]
+
+<p>
+
+[% PROCESS admin/fieldvalues/footer.html.tmpl %]
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/admin/table.html.tmpl b/template/en/default/admin/table.html.tmpl
index fd1382b14..4254f80e1 100644
--- a/template/en/default/admin/table.html.tmpl
+++ b/template/en/default/admin/table.html.tmpl
@@ -33,6 +33,12 @@
# content: If specified, the content of this variable is used
# instead of the data pulled from the current row.
# NOTE: This value is not HTML filtered at output!
+ # content_use_field: If defined and true, then each value in the
+ # column corresponds with a key in the
+ # field_descs field, and that value from the
+ # field_descs hash will be used instead of "content."
+ # See fieldvalues/select-field for an example of use.
+ # This content WILL be HTML-filtered in this case.
# align: left/center/right. Controls the horizontal alignment of the
# text in the column.
# allow_html_content: if defined, then this column allows html content
@@ -46,6 +52,8 @@
#
#%]
+[% PROCESS "global/field-descs.none.tmpl" %]
+
[%################### TABLE HEADER ######################%]
<table border="1" cellpadding="4" cellspacing="0">
@@ -77,8 +85,11 @@
<a href="[% link_uri %]">
[% END %]
- [% IF c.content %]
- [% c.content %]
+ [% IF c.content_use_field %]
+ [% colname = row.${c.name} %]
+ [% field_descs.${colname} FILTER html %]
+ [% ELSIF c.content %]
+ [% c.content %]
[% ELSE %]
[% IF c.yesno_field %]
[% IF row.${c.name} %]
diff --git a/template/en/default/global/useful-links.html.tmpl b/template/en/default/global/useful-links.html.tmpl
index b9a69a9e9..eb8c7e24c 100644
--- a/template/en/default/global/useful-links.html.tmpl
+++ b/template/en/default/global/useful-links.html.tmpl
@@ -78,19 +78,15 @@
IF user.groups.tweakparams %]
[% ' | <a href="editusers.cgi">Users</a>' IF user.groups.editusers
|| user.can_bless %]
- [% IF Param('useclassification') %]
- [% IF user.groups.editclassifications %]
+ [% IF Param('useclassification') && user.groups.editclassifications %]
[% ' | <a href="editclassifications.cgi">Classifications</a>' %]
- [% END %]
- [% IF user.groups.editcomponents %]
- [% ' | <a href="editproducts.cgi">Products</a>' %]
- [% END %]
- [% ELSE %]
- [% ' | <a href="editproducts.cgi">Products</a>'
+ [% END %]
+ [% ' | <a href="editproducts.cgi">Products</a>'
IF user.groups.editcomponents %]
- [% END %]
[% ' | <a href="editflagtypes.cgi">Flags</a>'
IF user.groups.editcomponents %]
+ [% ' | <a href="editvalues.cgi">Field Values</a>'
+ IF user.groups.editcomponents %]
[% ' | <a href="editgroups.cgi">Groups</a>'
IF user.groups.creategroups %]
[% ' | <a href="editkeywords.cgi">Keywords</a>'
diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
index 55c796924..47dcaca10 100644
--- a/template/en/default/global/user-error.html.tmpl
+++ b/template/en/default/global/user-error.html.tmpl
@@ -321,6 +321,49 @@
Sorry; you do not have the permissions necessary to enter [% terms.abug %]
against the [% product FILTER html %] product.
+ [% ELSIF error == "fieldname_invalid" %]
+ [% title = "Specified Field Does Not Exist" %]
+ The field '[% field FILTER html %]' does not exist or
+ cannot be edited with this interface.
+
+ [% ELSIF error == "fieldname_not_specified" %]
+ [% title = "Field Name Not Specified" %]
+ No field name specified when trying to edit field values.
+
+ [% ELSIF error == "fieldvalue_already_exists" %]
+ [% title = "Field Value Already Exists" %]
+ The value '[% value FILTER html %]' already exists for the
+ '[%- field FILTER html %]' field.
+
+ [% ELSIF error == "fieldvalue_doesnt_exist" %]
+ [% title = "Specified Field Value Does Not Exist" %]
+ The value '[% value FILTER html %]' does not exist for
+ the '[% field FILTER html %]' field.
+
+ [% ELSIF error == "fieldvalue_name_too_long" %]
+ [% title = "Field Value Is Too Long" %]
+ The value of a field is limited to 60 characters.
+ '[% value FILTER html %]' is too long ([% value.length %] characters).
+
+ [% ELSIF error == "fieldvalue_not_specified" %]
+ [% title = "Field Value Not Specified" %]
+ No field value specified when trying to edit a field value.
+
+ [% ELSIF error == "fieldvalue_sortkey_invalid" %]
+ [% title = "Invalid Field Value Sortkey" %]
+ The sortkey '[% sortkey FILTER html %]' for the '[% name FILTER html %]'
+ field is not a valid (positive) number.
+
+ [% ELSIF error == "fieldvalue_still_has_bugs" %]
+ [% title = "You Cannot Delete This Field Value" %]
+ You cannot delete the value '[% value FILTER html %]' from the
+ '[% field FILTER html%]' field, because there are still
+ [% count FILTER html %] [% terms.bugs %] using it.
+
+ [% ELSIF error == "fieldvalue_undefined" %]
+ [% title = "Undefined Value Not Allowed" %]
+ You must specify a value.
+
[% ELSIF error == "file_not_specified" %]
[% title = "No File Specified" %]
You did not specify a file to attach.