editfields.cgi: code style, remove CGI usage, warn on default/value field changes; editvalues.cgi: call update_control_lists

hinted-selects
Vitaliy Filippov 2014-08-26 15:59:45 +04:00
parent a5ce0f5c92
commit 16a1c9d3f7
7 changed files with 125 additions and 97 deletions

View File

@ -131,7 +131,7 @@ use constant UPDATE_VALIDATORS => {
default_value => \&_check_default_value,
};
use constant UPDATE_COLUMNS => grep { $_ ne 'id' } DB_COLUMNS();
use constant UPDATE_COLUMNS => grep { $_ ne 'id' && $_ ne 'custom' } DB_COLUMNS();
# How various field types translate into SQL data definitions.
use constant SQL_DEFINITIONS => {
@ -845,7 +845,7 @@ sub remove_from_db
if (!$self->custom)
{
ThrowCodeError('field_not_custom', { name => $name });
ThrowUserError('field_not_custom', { name => $name });
}
if (!$self->obsolete)
@ -970,6 +970,21 @@ sub flag_field
return $self->clone_field if $flag == FLAG_CLONED;
}
sub clear_value_visibility_values
{
my $self = shift;
Bugzilla->dbh->do(
"DELETE FROM fieldvaluecontrol WHERE field_id=? AND value_id > 0",
undef, $self->id
);
}
sub clear_default_values
{
my $self = shift;
Bugzilla->dbh->do("DELETE FROM field_defaults WHERE field_id=?", undef, $self->id);
}
sub update_visibility_values
{
my $self = shift;

View File

@ -1,6 +1,4 @@
#!/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
@ -25,8 +23,8 @@ use Bugzilla::Util;
use Bugzilla::Field;
use Bugzilla::Token;
my $cgi = Bugzilla->cgi;
my $template = Bugzilla->template;
my $ARGS = Bugzilla->input_params;
my $vars = {};
# Make sure the user is logged in and is an administrator.
@ -37,8 +35,8 @@ $user->in_group('editfields') || ThrowUserError('auth_failure', {
object => 'custom_fields',
});
my $action = trim($cgi->param('action') || '');
my $token = $cgi->param('token');
my $action = trim($ARGS->{action} || '');
my $token = $ARGS->{token};
$vars->{field_types} = Bugzilla->messages->{field_types};
# List all existing custom fields if no action is given.
@ -59,38 +57,29 @@ elsif ($action eq 'new')
check_token_data($token, 'add_field');
my $field = $vars->{field} = Bugzilla::Field->create({
name => scalar $cgi->param('name'),
url => scalar $cgi->param('url'),
description => scalar $cgi->param('desc'),
type => scalar $cgi->param('type'),
sortkey => scalar $cgi->param('sortkey'),
mailhead => scalar $cgi->param('new_bugmail'),
clone_bug => scalar $cgi->param('clone_bug'),
obsolete => scalar $cgi->param('obsolete'),
is_mandatory => !scalar $cgi->param('nullable'),
custom => 1,
visibility_field_id => scalar $cgi->param('visibility_field_id'),
value_field_id => scalar $cgi->param('value_field_id'),
add_to_deps => scalar $cgi->param('add_to_deps'),
map { ($_ => $ARGS->{$_}) } Bugzilla::Field->DB_COLUMNS,
custom => 1,
is_mandatory => !$ARGS->{nullable},
});
$field->set_visibility_values([ $cgi->param('visibility_value_id') ]);
$field->set_null_visibility_values([ $cgi->param('null_visibility_values') ]);
$field->set_visibility_values([ list $ARGS->{visibility_value_id} ]);
$field->set_null_visibility_values([ list $ARGS->{null_visibility_values} ]);
$field->set_clone_visibility_values([ list $ARGS->{clone_visibility_values} ]);
delete_token($token);
$vars->{'message'} = 'custom_field_created';
$vars->{message} = 'custom_field_created';
$template->process('admin/custom_fields/list.html.tmpl', $vars)
|| ThrowTemplateError($template->error());
}
elsif ($action eq 'edit')
{
my $name = $cgi->param('name') || ThrowUserError('field_missing_name');
my $name = $ARGS->{name} || ThrowUserError('field_missing_name');
my $field = Bugzilla->get_field($name);
$field || ThrowUserError('customfield_nonexistent', {'name' => $name});
$field || ThrowUserError('customfield_nonexistent', { name => $name });
$vars->{'field'} = $field;
$vars->{'token'} = issue_session_token('edit_field');
$vars->{field} = $field;
$vars->{token} = issue_session_token('edit_field');
$template->process('admin/custom_fields/edit.html.tmpl', $vars)
|| ThrowTemplateError($template->error());
@ -98,46 +87,52 @@ elsif ($action eq 'edit')
elsif ($action eq 'update')
{
check_token_data($token, 'edit_field');
my $name = $cgi->param('name');
# Validate fields.
$name || ThrowUserError('field_missing_name');
my $name = $ARGS->{name} || ThrowUserError('field_missing_name');
my $field = Bugzilla->get_field($name);
$field || ThrowUserError('customfield_nonexistent', {'name' => $name});
$field || ThrowUserError('customfield_nonexistent', { name => $name });
$vars->{field} = $field;
$field->set_description(scalar $cgi->param('desc'));
$field->set_sortkey(scalar $cgi->param('sortkey'));
$field->set_url(scalar $cgi->param('url'));
$field->set_add_to_deps($cgi->param('add_to_deps'));
if ($field->can_tweak('mailhead'))
if ($field->can_tweak('value_field_id') &&
($ARGS->{value_field_id} || 0) != ($field->value_field_id || 0))
{
$field->set_in_new_bugmail(scalar $cgi->param('new_bugmail'));
if (!$ARGS->{force_changes} && $field->value_field_id)
{
my $h = Bugzilla->fieldvaluecontrol->{$field->value_field_id}->{values}->{$field->id};
$vars->{value_dep_count} = scalar keys %{ { map { %$_ } values %$h } };
}
if (!$vars->{value_dep_count})
{
$field->set('value_field_id', $ARGS->{value_field_id});
$field->clear_value_visibility_values;
}
}
if ($field->can_tweak('obsolete'))
if ($field->can_tweak('default_field_id') &&
($ARGS->{default_field_id} || 0) != ($field->default_field_id || 0))
{
$field->set_obsolete(scalar $cgi->param('obsolete'));
if (!$ARGS->{force_changes} && $field->default_field_id)
{
my $h = Bugzilla->fieldvaluecontrol->{$field->default_field_id}->{defaults}->{$field->id};
$vars->{default_count} = scalar keys %$h;
}
if (!$vars->{default_count})
{
$field->set('default_field_id', $ARGS->{default_field_id});
$field->clear_default_values;
}
}
if ($field->can_tweak('nullable'))
if ($vars->{default_count} || $vars->{value_dep_count})
{
$field->set_is_mandatory(!scalar $cgi->param('nullable'));
$template->process('admin/custom_fields/confirm-changes.html.tmpl', $vars)
|| ThrowTemplateError($template->error());
exit;
}
if ($field->can_tweak('default_value'))
for (grep { !/_field_id/ && $_ ne 'is_mandatory' } Bugzilla::Field->UPDATE_COLUMNS)
{
$field->set_default_value($field->type == FIELD_TYPE_MULTI_SELECT ? [ $cgi->param('default_value') ] : scalar $cgi->param('default_value'));
}
if ($field->can_tweak('clone_bug'))
{
$field->set_clone_bug(scalar $cgi->param('clone_bug'));
}
if ($field->can_tweak('value_field_id'))
{
$field->set_value_field(scalar $cgi->param('value_field_id'));
}
if ($field->can_tweak('default_field_id'))
{
# FIXME Disallow to change default field if it will lead to losing all the default values
$field->set_default_field($cgi->param('default_field_id'));
$field->set($_, $ARGS->{$_}) if $field->can_tweak($_);
}
$field->set_is_mandatory(!$ARGS->{nullable}) if $field->can_tweak('nullable');
for (
[ qw(visibility_field_id set_visibility_field set_visibility_values visibility_value_id) ],
[ qw(null_field_id set_null_field set_null_visibility_values null_visibility_values) ],
@ -145,7 +140,7 @@ elsif ($action eq 'update')
) {
if ($field->can_tweak($_->[0]))
{
my $vf = $cgi->param($_->[0]);
my $vf = $ARGS->{$_->[0]};
if ($vf ne $field->${\$_->[0]}())
{
$field->${\$_->[1]}($vf);
@ -153,7 +148,7 @@ elsif ($action eq 'update')
}
else
{
$field->${\$_->[2]}([ $cgi->param($_->[3]) ]);
$field->${\$_->[2]}([ list $ARGS->{$_->[3]} ]);
}
}
}
@ -161,28 +156,21 @@ elsif ($action eq 'update')
delete_token($token);
$vars->{'field'} = $field;
$vars->{'message'} = 'custom_field_updated';
$vars->{message} = 'custom_field_updated';
$template->process('admin/custom_fields/list.html.tmpl', $vars)
|| ThrowTemplateError($template->error());
}
elsif ($action eq 'del')
{
my $name = $cgi->param('name');
# Validate field.
$name || ThrowUserError('field_missing_name');
# Do not allow deleting non-custom fields.
# Custom field names must start with "cf_".
if ($name !~ /^cf_/) {
$name = 'cf_' . $name;
}
my $name = $ARGS->{name} || ThrowUserError('field_missing_name');
my $field = Bugzilla->get_field($name);
$field || ThrowUserError('customfield_nonexistent', {'name' => $name});
$field || ThrowUserError('customfield_nonexistent', { name => $name });
$field->custom || ThrowUserError('field_not_custom', { name => $name });
$field->obsolete || ThrowUserError('field_not_obsolete', { name => $name });
$vars->{'field'} = $field;
$vars->{'token'} = issue_session_token('delete_field');
$vars->{field} = $field;
$vars->{token} = issue_session_token('delete_field');
$template->process('admin/custom_fields/confirm-delete.html.tmpl', $vars)
|| ThrowTemplateError($template->error());
@ -190,24 +178,16 @@ elsif ($action eq 'del')
elsif ($action eq 'delete')
{
check_token_data($token, 'delete_field');
my $name = $cgi->param('name');
# Validate fields.
$name || ThrowUserError('field_missing_name');
# Do not allow deleting non-custom fields.
# Custom field names must start with "cf_".
if ($name !~ /^cf_/) {
$name = 'cf_' . $name;
}
my $name = $ARGS->{name} || ThrowUserError('field_missing_name');
my $field = Bugzilla->get_field($name);
$field || ThrowUserError('customfield_nonexistent', {'name' => $name});
$field || ThrowUserError('customfield_nonexistent', { name => $name });
# Calling remove_from_db will check if field can be deleted.
# If the field cannot be deleted, it will throw an error.
$field->remove_from_db();
$vars->{'field'} = $field;
$vars->{'message'} = 'custom_field_deleted';
$vars->{field} = $field;
$vars->{message} = 'custom_field_deleted';
delete_token($token);
@ -216,5 +196,6 @@ elsif ($action eq 'delete')
}
else
{
ThrowUserError('no_valid_action', {'field' => 'custom_field'});
ThrowUserError('no_valid_action', { field => 'custom_field' });
}
exit;

View File

@ -168,6 +168,7 @@ if ($action eq 'update')
{
$vars->{changes}->{visibility_values} = $value->set_visibility_values($ARGS->{visibility_value_id});
}
$vars->{changes}->{control_lists} = 1 if $field->update_control_lists($value->id, $ARGS);
delete_token($token);
$vars->{changes} = $value->update;
$vars->{message} = 'field_value_updated';

View File

@ -0,0 +1,31 @@
[%# Warning about data loss when changing value field or default field
# License: Dual-license GPL 3.0+ or MPL 1.1+
# Author: Vitaliy Filippov <vitalif@mail.ru>
#%]
[% PROCESS global/header.html.tmpl title='Confirm Changes' %]
<div class="user-error-div">
<form action="[% script_name %]" method="post" style="margin-top: 0" enctype="multipart/form-data">
<h3 style="margin: 0">Confirm Changes</h3>
[% IF value_dep_count %]
<p>
Warning: value dependencies are set for [% value_dep_count %] values of
[%+ field.value_field.description | html %] field. They will be <b>lost</b> when
changing value controlling field.
</p>
[% END %]
[% IF default_count %]
<p>
Warning: default [% field.description | html %] values are set for [% default_count %] values of
[%+ field.default_field.description | html %] field. They will be <b>lost</b> when
changing default controlling field.
</p>
[% END %]
[% PROCESS "global/hidden-fields.html.tmpl" %]
<input type="hidden" name="force_changes" value="1" />
<input type="submit" value="Clear dependencies and save changes" />
</form>
</div>
[% PROCESS global/footer.html.tmpl %]

View File

@ -102,14 +102,14 @@ var constants = {
</td>
[% IF !field.id || field.can_tweak('mailhead') %]
<th align="left">
<label for="new_bugmail">Displayed in [% terms.bug %]mail for new [% terms.bugs %]:</label>
<label for="mailhead">Displayed in [% terms.bug %]mail for new [% terms.bugs %]:</label>
</th>
<td><input type="checkbox" id="new_bugmail" name="new_bugmail" value="1" [%- " checked" IF field.in_new_bugmail %] /></td>
<td><input type="checkbox" id="mailhead" name="mailhead" value="1" [%- " checked" IF field.in_new_bugmail %] /></td>
[% END %]
</tr>
<tr>
<th align="left"><label for="desc">Title:</label></th>
<td><input type="text" id="desc" name="desc" style="width: 400px" value="[% field.description | html %]" /></td>
<th align="left"><label for="description">Title:</label></th>
<td><input type="text" id="description" name="description" style="width: 400px" value="[% field.description | html %]" /></td>
[% IF !field.id || field.can_tweak('clone_bug') %]
<th align="left"><label for="clone_bug">Is copied into the cloned [% terms.bug %]:</label></th>
<td><input type="checkbox" id="clone_bug" name="clone_bug" value="1" [%- " checked" IF field.clone_bug %] onclick="onChangeCloned()" /></td>

View File

@ -242,11 +242,6 @@
on Bugzilla::Field::Choice).
[% END %]
[% BLOCK error_field_not_custom %]
'[% field.description FILTER html %]' ([% field.name FILTER html %])
is not a custom field.
[% END %]
[% BLOCK error_field_type_not_specified %]
[% title = "Field Type Not Specified" %]
You must specify a type when creating a custom field.

View File

@ -431,9 +431,9 @@
[% END %]
[% BLOCK error_customfield_not_obsolete %]
[% title = "Custom Field Not Obsolete" %]
The custom field '[% name FILTER html %]' is not obsolete.
Please obsolete a custom field before attempting to delete it.
[% title = "Custom Field Not Disabled" %]
The custom field '[% name | html %]' is not disabled.
Please disable a custom field before attempting to delete it.
[% END %]
[% BLOCK error_customfield_has_contents %]
@ -558,6 +558,11 @@
is not the right type of field.
[% END %]
[% BLOCK error_field_not_custom %]
[% title = "Only Custom Fields May Be Deleted" %]
Field [% name | html %] is non-custom and therefore may not be deleted.
[% END %]
[% BLOCK error_direct_field_needed_for_reverse %]
[% title = "Invalid Direct Field selected" %]
Each field of type "[% lc_messages.field_types.${constants.FIELD_TYPE_BUG_ID_REV} %]" must correspond