Remove non-hash Bugzilla->fieldvaluecontrol, move dependent default values into a separate table, simplify bz_add_column
parent
4f20f1242c
commit
74ecc3d2c5
33
Bugzilla.pm
33
Bugzilla.pm
|
@ -932,13 +932,13 @@ sub fieldvaluecontrol
|
|||
my $cache = $class->cache_fields;
|
||||
if (!$cache->{fieldvaluecontrol})
|
||||
{
|
||||
$cache->{fieldvaluecontrol} = $class->dbh->selectall_arrayref(
|
||||
my $rows = $class->dbh->selectall_arrayref(
|
||||
'SELECT c.*, (CASE WHEN c.value_id <= 0 THEN f.visibility_field_id ELSE f.value_field_id END) visibility_field_id'.
|
||||
' FROM fieldvaluecontrol c, fielddefs f WHERE f.id=c.field_id'.
|
||||
' ORDER BY c.field_id, c.value_id, (CASE WHEN c.value_id=0 THEN f.visibility_field_id ELSE f.value_field_id END), c.visibility_value_id', {Slice=>{}}
|
||||
);
|
||||
my $has = {};
|
||||
for (@{$cache->{fieldvaluecontrol}})
|
||||
for (@$rows)
|
||||
{
|
||||
if ($_->{value_id} > 0)
|
||||
{
|
||||
|
@ -947,8 +947,7 @@ sub fieldvaluecontrol
|
|||
->{values}
|
||||
->{$_->{field_id}}
|
||||
->{$_->{value_id}}
|
||||
->{$_->{visibility_value_id}}
|
||||
->{is_default} = $_->{is_default};
|
||||
->{$_->{visibility_value_id}} = 1;
|
||||
}
|
||||
elsif (!$_->{value_id})
|
||||
{
|
||||
|
@ -967,22 +966,24 @@ sub fieldvaluecontrol
|
|||
->{$_->{visibility_value_id}} = 1;
|
||||
}
|
||||
}
|
||||
$cache->{fieldvaluecontrol_hash} = $has;
|
||||
# Dependent defaults
|
||||
$rows = $class->dbh->selectall_arrayref(
|
||||
# FIXME: it will be default_field_id
|
||||
'SELECT d.field_id, f.visibility_field_id, d.visibility_value_id, d.default_value'.
|
||||
' FROM field_defaults d, fielddefs f WHERE f.id=d.field_id', {Slice=>{}}
|
||||
);
|
||||
for (@$rows)
|
||||
{
|
||||
$has->{$_->{visibility_field_id}}
|
||||
->{defaults}
|
||||
->{$_->{field_id}}
|
||||
->{$_->{visibility_value_id}} = $_->{default_value};
|
||||
}
|
||||
$cache->{fieldvaluecontrol} = $has;
|
||||
}
|
||||
return $cache->{fieldvaluecontrol};
|
||||
}
|
||||
|
||||
sub fieldvaluecontrol_hash
|
||||
{
|
||||
my $class = shift;
|
||||
my $cache = $class->cache_fields;
|
||||
if (!$cache->{fieldvaluecontrol_hash})
|
||||
{
|
||||
$class->fieldvaluecontrol;
|
||||
}
|
||||
return $cache->{fieldvaluecontrol_hash};
|
||||
}
|
||||
|
||||
sub full_json_visibility
|
||||
{
|
||||
my $class = shift;
|
||||
|
|
|
@ -538,6 +538,14 @@ sub bz_drop_foreign_keys {
|
|||
sub bz_add_column {
|
||||
my ($self, $table, $name, $new_def, $init_value) = @_;
|
||||
|
||||
if (!$new_def) {
|
||||
# Take default definition from schema, but exclude REFERENCES
|
||||
$new_def = $self->_bz_schema->get_column_abstract($table, $name)
|
||||
|| die "bz_add_column: unknown column $table.$name";
|
||||
$new_def = { %$new_def };
|
||||
delete $new_def->{REFERENCES};
|
||||
}
|
||||
|
||||
# You can't add a NOT NULL column to a table with
|
||||
# no DEFAULT statement, unless you have an init_value.
|
||||
# SERIAL types are an exception, though, because they can
|
||||
|
|
|
@ -549,27 +549,24 @@ use constant ABSTRACT_SCHEMA => {
|
|||
|
||||
fielddefs => {
|
||||
FIELDS => [
|
||||
id => {TYPE => 'INTSERIAL', NOTNULL => 1, PRIMARYKEY => 1},
|
||||
name => {TYPE => 'varchar(255)', NOTNULL => 1},
|
||||
type => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => FIELD_TYPE_UNKNOWN},
|
||||
custom => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
description => {TYPE => 'TINYTEXT', NOTNULL => 1},
|
||||
mailhead => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
sortkey => {TYPE => 'INT2', NOTNULL => 1},
|
||||
obsolete => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
clone_bug => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
is_mandatory => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
id => {TYPE => 'INTSERIAL', NOTNULL => 1, PRIMARYKEY => 1},
|
||||
name => {TYPE => 'varchar(255)', NOTNULL => 1},
|
||||
type => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => FIELD_TYPE_UNKNOWN},
|
||||
custom => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
description => {TYPE => 'TINYTEXT', NOTNULL => 1},
|
||||
mailhead => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
sortkey => {TYPE => 'INT2', NOTNULL => 1},
|
||||
obsolete => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
clone_bug => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
is_mandatory => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'},
|
||||
url => {TYPE => 'VARCHAR(255)'}, # template for FIELD_TYPE_EXTURL
|
||||
delta_ts => {TYPE => 'DATETIME'}, # for refreshing client-side cache
|
||||
has_activity => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0},
|
||||
add_to_deps => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}, # for FIELD_TYPE_BUG_ID
|
||||
default_value => {TYPE => 'MEDIUMTEXT'},
|
||||
# Fields that change the behaviour of this one in various ways
|
||||
visibility_field_id => {TYPE => 'INT4', REFERENCES => {TABLE => 'fielddefs', COLUMN => 'id'}},
|
||||
# CustIS Bug 53617 - visibility_value_id is removed from here
|
||||
# (migrated to fieldvaluecontrol table)
|
||||
value_field_id => {TYPE => 'INT4', REFERENCES => {TABLE => 'fielddefs', COLUMN => 'id'}},
|
||||
# Used for "external link via template" type fields (CustIS Bug 90854)
|
||||
url => {TYPE => 'VARCHAR(255)'},
|
||||
# Used for refreshing client-side field/value cache (CustIS Bug 70605)
|
||||
delta_ts => {TYPE => 'DATETIME'},
|
||||
has_activity => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0},
|
||||
# Automatic addition of Bug ID field value dependencies (CustIS Bug 73054)
|
||||
add_to_deps => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0},
|
||||
value_field_id => {TYPE => 'INT4', REFERENCES => {TABLE => 'fielddefs', COLUMN => 'id'}},
|
||||
],
|
||||
INDEXES => [
|
||||
fielddefs_name_idx => {FIELDS => ['name'], TYPE => 'UNIQUE'},
|
||||
|
@ -578,6 +575,18 @@ use constant ABSTRACT_SCHEMA => {
|
|||
],
|
||||
},
|
||||
|
||||
# Default values
|
||||
field_defaults => {
|
||||
FIELDS => [
|
||||
field_id => {TYPE => 'INT4', NOTNULL => 1},
|
||||
visibility_value_id => {TYPE => 'INT4', NOTNULL => 1},
|
||||
default_value => {TYPE => 'MEDIUMTEXT', NOTNULL => 1},
|
||||
],
|
||||
INDEXES => [
|
||||
fieldvaluecontrol_primary_idx => {FIELDS => ['field_id', 'visibility_value_id'], TYPE => 'PRIMARY'},
|
||||
],
|
||||
},
|
||||
|
||||
# All value/value and value/field dependencies are stored here
|
||||
# value_id > 0: value with this id is visible if value field has value visibility_value_id
|
||||
# value_id == 0: field is visible if visibility field has value visibility_value_id
|
||||
|
@ -588,7 +597,6 @@ use constant ABSTRACT_SCHEMA => {
|
|||
field_id => {TYPE => 'INT4', NOTNULL => 1},
|
||||
value_id => {TYPE => 'INT4', NOTNULL => 1},
|
||||
visibility_value_id => {TYPE => 'INT4', NOTNULL => 1},
|
||||
is_default => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0},
|
||||
],
|
||||
INDEXES => [
|
||||
fieldvaluecontrol_primary_idx => {FIELDS => ['field_id', 'visibility_value_id', 'value_id'], TYPE => 'UNIQUE'},
|
||||
|
@ -2099,6 +2107,7 @@ sub get_column_abstract {
|
|||
# Prevent a possible dereferencing of an undef hash, if the
|
||||
# table doesn't exist.
|
||||
if ($self->get_table_abstract($table)) {
|
||||
# FIXME This hash is recreated each time you call get_column_abstract... :-(
|
||||
my %fields = (@{ $self->{abstract_schema}{$table}{FIELDS} });
|
||||
return $fields{$column};
|
||||
}
|
||||
|
|
|
@ -102,12 +102,13 @@ use constant DB_COLUMNS => qw(
|
|||
obsolete
|
||||
is_mandatory
|
||||
clone_bug
|
||||
visibility_field_id
|
||||
value_field_id
|
||||
delta_ts
|
||||
has_activity
|
||||
add_to_deps
|
||||
url
|
||||
default_value
|
||||
visibility_field_id
|
||||
value_field_id
|
||||
);
|
||||
|
||||
use constant REQUIRED_CREATE_FIELDS => qw(name description);
|
||||
|
@ -126,24 +127,11 @@ use constant VALIDATORS => {
|
|||
};
|
||||
|
||||
use constant UPDATE_VALIDATORS => {
|
||||
value_field_id => \&_check_value_field_id,
|
||||
value_field_id => \&_check_value_field_id,
|
||||
default_value => \&_check_default_value,
|
||||
};
|
||||
|
||||
use constant UPDATE_COLUMNS => qw(
|
||||
description
|
||||
mailhead
|
||||
sortkey
|
||||
obsolete
|
||||
is_mandatory
|
||||
clone_bug
|
||||
visibility_field_id
|
||||
value_field_id
|
||||
type
|
||||
delta_ts
|
||||
has_activity
|
||||
add_to_deps
|
||||
url
|
||||
);
|
||||
use constant UPDATE_COLUMNS => grep { $_ ne 'type' && $_ ne 'id' } DB_COLUMNS();
|
||||
|
||||
# How various field types translate into SQL data definitions.
|
||||
use constant SQL_DEFINITIONS => {
|
||||
|
@ -373,6 +361,28 @@ sub _check_add_to_deps
|
|||
return $addto{$value || ''};
|
||||
}
|
||||
|
||||
sub _check_default_value
|
||||
{
|
||||
my ($self, $value) = @_;
|
||||
if ($self->type == FIELD_TYPE_SINGLE_SELECT)
|
||||
{
|
||||
# ID
|
||||
detaint_natural($value) || undef;
|
||||
}
|
||||
elsif ($self->type == FIELD_TYPE_MULTI_SELECT)
|
||||
{
|
||||
# Array of IDs
|
||||
$value = [ $value ] if !ref $value;
|
||||
detaint_natural($_) for @$value;
|
||||
$value = @$value ? join(',', @$value) : undef;
|
||||
}
|
||||
elsif ($self->type == FIELD_TYPE_BUG_ID_REV)
|
||||
{
|
||||
return undef;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 Instance Properties
|
||||
|
@ -521,6 +531,10 @@ sub add_to_deps { $_[0]->type == FIELD_TYPE_BUG_ID && $_[0]->{add_to_deps} }
|
|||
|
||||
sub url { $_[0]->{url} }
|
||||
|
||||
sub default_value { $_[0]->{default_value} }
|
||||
|
||||
sub default_value_hash { $_[0]->is_select ? { map { $_ => 1 } split /,/, $_[0]->{default_value} } : undef }
|
||||
|
||||
sub value_type
|
||||
{
|
||||
my $self = shift;
|
||||
|
@ -567,7 +581,7 @@ sub restricted_legal_values
|
|||
my $rc_cache = Bugzilla->rc_cache_fields;
|
||||
if (!$rc_cache->{$self}->{restricted_legal_values}->{$controller_value})
|
||||
{
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash->{$self->value_field_id}->{values}->{$self->id};
|
||||
my $hash = Bugzilla->fieldvaluecontrol->{$self->value_field_id}->{values}->{$self->id};
|
||||
$rc_cache->{$self}->{restricted_legal_values}->{$controller_value} = [
|
||||
grep {
|
||||
$_->is_static || !exists $hash->{$_->id} ||
|
||||
|
@ -578,29 +592,6 @@ sub restricted_legal_values
|
|||
return $rc_cache->{$self}->{restricted_legal_values}->{$controller_value};
|
||||
}
|
||||
|
||||
# Select default values for a named value of controlling field
|
||||
sub get_default_values
|
||||
{
|
||||
my $self = shift;
|
||||
my ($controller_value) = @_;
|
||||
return [] unless $self->value_field;
|
||||
my @values;
|
||||
my $field_values = $self->value_field->legal_values;
|
||||
foreach my $field_value (@$field_values)
|
||||
{
|
||||
if ($field_value->{name} eq $controller_value)
|
||||
{
|
||||
my $cvalues = $self->legal_values;
|
||||
foreach my $value (@$cvalues)
|
||||
{
|
||||
push @values, $value->{value} if $value->is_default_controlled_value($field_value->{id}) && !$value->is_static;
|
||||
}
|
||||
last;
|
||||
}
|
||||
}
|
||||
return \@values;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=over
|
||||
|
@ -636,7 +627,7 @@ sub visibility_values
|
|||
{
|
||||
my $self = shift;
|
||||
return undef if !$self->visibility_field_id;
|
||||
my $h = Bugzilla->fieldvaluecontrol_hash
|
||||
my $h = Bugzilla->fieldvaluecontrol
|
||||
->{$self->visibility_field_id}->{fields}->{$self->id};
|
||||
return $h && %$h ? $h : undef;
|
||||
}
|
||||
|
@ -647,7 +638,7 @@ sub has_visibility_value
|
|||
return 1 if !$self->visibility_field_id;
|
||||
my ($value) = @_;
|
||||
$value = $value->id if ref $value;
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash
|
||||
my $hash = Bugzilla->fieldvaluecontrol
|
||||
->{$self->visibility_field_id}->{fields}->{$self->id};
|
||||
return !$hash || !%$hash || $hash->{$value};
|
||||
}
|
||||
|
@ -656,7 +647,7 @@ sub null_visibility_values
|
|||
{
|
||||
my $self = shift;
|
||||
return undef if !$self->visibility_field_id;
|
||||
my $h = Bugzilla->fieldvaluecontrol_hash
|
||||
my $h = Bugzilla->fieldvaluecontrol
|
||||
->{$self->visibility_field_id}->{null}->{$self->id};
|
||||
return $h && %$h ? $h : undef;
|
||||
}
|
||||
|
@ -785,14 +776,15 @@ They will throw an error if you try to set the values to something invalid.
|
|||
|
||||
=cut
|
||||
|
||||
sub set_description { $_[0]->set('description', $_[1]); }
|
||||
sub set_clone_bug { $_[0]->set('clone_bug', $_[1]); }
|
||||
sub set_obsolete { $_[0]->set('obsolete', $_[1]); }
|
||||
sub set_is_mandatory { $_[0]->set('is_mandatory', $_[1]); }
|
||||
sub set_sortkey { $_[0]->set('sortkey', $_[1]); }
|
||||
sub set_in_new_bugmail { $_[0]->set('mailhead', $_[1]); }
|
||||
sub set_add_to_deps { $_[0]->set('add_to_deps', $_[1]); }
|
||||
sub set_url { $_[0]->set('url', $_[1]); }
|
||||
sub set_description { $_[0]->set('description', $_[1]); }
|
||||
sub set_clone_bug { $_[0]->set('clone_bug', $_[1]); }
|
||||
sub set_obsolete { $_[0]->set('obsolete', $_[1]); }
|
||||
sub set_is_mandatory { $_[0]->set('is_mandatory', $_[1]); }
|
||||
sub set_sortkey { $_[0]->set('sortkey', $_[1]); }
|
||||
sub set_in_new_bugmail { $_[0]->set('mailhead', $_[1]); }
|
||||
sub set_add_to_deps { $_[0]->set('add_to_deps', $_[1]); }
|
||||
sub set_url { $_[0]->set('url', $_[1]); }
|
||||
sub set_default_value { $_[0]->set('default_value', $_[1]); }
|
||||
|
||||
sub set_visibility_field
|
||||
{
|
||||
|
@ -1064,6 +1056,13 @@ sub run_create_validators
|
|||
$params->{url} = undef;
|
||||
}
|
||||
|
||||
# Check default value
|
||||
if ($type == FIELD_TYPE_SINGLE_SELECT || $type == FIELD_TYPE_MULTI_SELECT ||
|
||||
$type == FIELD_TYPE_BUG_ID || $type == FIELD_TYPE_BUG_ID_REV)
|
||||
{
|
||||
$params->{default_value} = undef;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
|
@ -1324,7 +1323,7 @@ sub toggle_value
|
|||
|
||||
sub update_controlled_values
|
||||
{
|
||||
my ($controlled_field, $controlled_value_ids, $visibility_value_id, $default_value_ids) = @_;
|
||||
my ($controlled_field, $controlled_value_ids, $visibility_value_id) = @_;
|
||||
$controlled_value_ids ||= [];
|
||||
my $vis_field = $controlled_field->value_field;
|
||||
if (!$vis_field)
|
||||
|
@ -1333,11 +1332,6 @@ sub update_controlled_values
|
|||
}
|
||||
$controlled_field = Bugzilla->get_field($controlled_field) if !ref $controlled_field;
|
||||
$visibility_value_id = int($visibility_value_id);
|
||||
if ($visibility_value_id)
|
||||
{
|
||||
my $type = Bugzilla::Field::Choice->type($vis_field);
|
||||
$visibility_value_id = $type->new($visibility_value_id)->{id};
|
||||
}
|
||||
Bugzilla->dbh->do(
|
||||
"DELETE FROM fieldvaluecontrol WHERE field_id=? AND visibility_value_id=? AND value_id!=0",
|
||||
undef, $controlled_field->id, $visibility_value_id);
|
||||
|
@ -1345,13 +1339,9 @@ sub update_controlled_values
|
|||
{
|
||||
my $type = Bugzilla::Field::Choice->type($controlled_field);
|
||||
$controlled_value_ids = [ map { $_->id } @{ $type->new_from_list($controlled_value_ids) } ];
|
||||
if ($default_value_ids)
|
||||
{
|
||||
$default_value_ids = { map { $_->id => 1 } @{ $type->new_from_list($default_value_ids) } };
|
||||
}
|
||||
my $f = $controlled_field->id;
|
||||
my $sql = "INSERT INTO fieldvaluecontrol (field_id, visibility_value_id, value_id, is_default) VALUES ".
|
||||
join(",", map { "($f, $visibility_value_id, $_, " . ($default_value_ids->{$_} ? '1' : '0') . ')' } @$controlled_value_ids);
|
||||
my $sql = "INSERT INTO fieldvaluecontrol (field_id, visibility_value_id, value_id) VALUES ".
|
||||
join(",", map { "($f, $visibility_value_id, $_)" } @$controlled_value_ids);
|
||||
Bugzilla->dbh->do($sql);
|
||||
}
|
||||
# Touch the field
|
||||
|
@ -1361,15 +1351,24 @@ sub update_controlled_values
|
|||
|
||||
sub update_default_values
|
||||
{
|
||||
my ($controlled_field, $visibility_value_id, $default_value_ids) = @_;
|
||||
my ($controlled_field, $visibility_value_id, $default_value) = @_;
|
||||
$controlled_field = Bugzilla->get_field($controlled_field) if !ref $controlled_field;
|
||||
$visibility_value_id = int($visibility_value_id);
|
||||
$default_value_ids = [ map { int $_ } @$default_value_ids || (0) ];
|
||||
Bugzilla->dbh->do(
|
||||
'UPDATE fieldvaluecontrol SET is_default=(value_id IN ('.join(', ', @$default_value_ids).
|
||||
')) WHERE field_id=? AND visibility_value_id=? AND value_id!=0',
|
||||
undef, $controlled_field->id, $visibility_value_id
|
||||
);
|
||||
$default_value = $controlled_field->_check_default_value($default_value);
|
||||
if (!$default_value)
|
||||
{
|
||||
Bugzilla->dbh->do(
|
||||
'DELETE FROM field_defaults WHERE field_id=? AND visibility_value_id=?',
|
||||
undef, $controlled_field->id, $visibility_value_id
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bugzilla->dbh->do(
|
||||
'REPLACE INTO field_defaults (field_id, visibility_value_id, default_value) VALUES (?, ?, ?)',
|
||||
undef, $controlled_field->id, $visibility_value_id, $default_value
|
||||
);
|
||||
}
|
||||
# Touch the field
|
||||
$controlled_field->touch;
|
||||
return 1;
|
||||
|
@ -1388,7 +1387,7 @@ sub json_visibility
|
|||
values => {},
|
||||
null => {},
|
||||
};
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash->{$self->id};
|
||||
my $hash = Bugzilla->fieldvaluecontrol->{$self->id};
|
||||
for my $key (qw(fields values null))
|
||||
{
|
||||
$data->{$key} = { map { Bugzilla->get_field($_)->name => $hash->{$key}->{$_} } keys %{$hash->{$key}} };
|
||||
|
|
|
@ -235,7 +235,7 @@ sub get_all
|
|||
# Product field is a special case: it has access controls applied.
|
||||
# So if our values are controlled by product field value,
|
||||
# return only ones visible inside products visible to current user.
|
||||
my $h = Bugzilla->fieldvaluecontrol_hash
|
||||
my $h = Bugzilla->fieldvaluecontrol
|
||||
->{Bugzilla->get_field('product')->id}
|
||||
->{values}
|
||||
->{$f->id};
|
||||
|
@ -381,11 +381,9 @@ sub controls_visibility_of_fields
|
|||
my $vid = $self->id;
|
||||
my $fid = $self->field->id;
|
||||
$self->{controls_visibility_of_fields} ||= [
|
||||
map { Bugzilla->get_field($_->{field_id}) }
|
||||
grep { !$_->{value_id} &&
|
||||
$_->{visibility_value_id} == $vid &&
|
||||
$_->{visibility_field_id} == $fid }
|
||||
@{Bugzilla->fieldvaluecontrol}
|
||||
map { Bugzilla->get_field($_) }
|
||||
grep { Bugzilla->fieldvaluecontrol->{$fid}->{fields}->{$_}->{$vid} }
|
||||
keys %{Bugzilla->fieldvaluecontrol->{$fid}->{fields}}
|
||||
];
|
||||
return $self->{controls_visibility_of_fields};
|
||||
}
|
||||
|
@ -397,20 +395,15 @@ sub controls_visibility_of_field_values
|
|||
my $fid = $self->field->id;
|
||||
if (!$self->{controls_visibility_of_field_values})
|
||||
{
|
||||
my $h = Bugzilla->fieldvaluecontrol->{$fid}->{values};
|
||||
my $r = {};
|
||||
for (@{Bugzilla->fieldvaluecontrol})
|
||||
for my $f (keys %$h)
|
||||
{
|
||||
if ($_->{value_id} &&
|
||||
$_->{visibility_value_id} == $vid &&
|
||||
$_->{visibility_field_id} == $fid)
|
||||
{
|
||||
push @{$r->{$_->{field_id}}}, $_->{value_id};
|
||||
}
|
||||
my $t = [ grep { $h->{$f}->{$_}->{$vid} } keys %{$h->{$f}} ];
|
||||
$f = Bugzilla->get_field($f);
|
||||
$r->{$f->name} = $f->value_type->new_from_list($t) if @$t;
|
||||
}
|
||||
$self->{controls_visibility_of_field_values} = { map {
|
||||
Bugzilla->get_field($_)->name =>
|
||||
Bugzilla::Field::Choice->type(Bugzilla->get_field($_))->new_from_list($r->{$_})
|
||||
} keys %$r };
|
||||
$self->{controls_visibility_of_field_values} = $r;
|
||||
}
|
||||
return $self->{controls_visibility_of_field_values};
|
||||
}
|
||||
|
@ -421,7 +414,7 @@ sub visibility_values
|
|||
my $f;
|
||||
if ($self->field->value_field_id && !($f = $self->{visibility_values}))
|
||||
{
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash
|
||||
my $hash = Bugzilla->fieldvaluecontrol
|
||||
->{$self->field->value_field_id}
|
||||
->{values}
|
||||
->{$self->field->id}
|
||||
|
@ -444,7 +437,7 @@ sub has_visibility_value
|
|||
$default = 1 if !defined $default;
|
||||
return $default if !$self->field->value_field_id;
|
||||
$value = $value->id if ref $value;
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash
|
||||
my $hash = Bugzilla->fieldvaluecontrol
|
||||
->{$self->field->value_field_id}
|
||||
->{values}
|
||||
->{$self->field->id}
|
||||
|
@ -459,7 +452,7 @@ sub visible_for_all
|
|||
my ($default) = @_;
|
||||
$default = 0 if !defined $default;
|
||||
return $default if !$self->field->value_field_id;
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash
|
||||
my $hash = Bugzilla->fieldvaluecontrol
|
||||
->{$self->field->value_field_id}
|
||||
->{values}
|
||||
->{$self->field->id}
|
||||
|
@ -467,14 +460,6 @@ sub visible_for_all
|
|||
return !$hash || !%$hash;
|
||||
}
|
||||
|
||||
sub is_default_controlled_value
|
||||
{
|
||||
my $self = shift;
|
||||
my $result = $self->has_visibility_value(@_);
|
||||
return $result unless ref $result;
|
||||
return $result->{is_default};
|
||||
}
|
||||
|
||||
# Check visibility of field value for a bug or a hashref with default value names
|
||||
sub check_visibility
|
||||
{
|
||||
|
|
|
@ -37,7 +37,8 @@ use Time::HiRes qw(time);
|
|||
|
||||
# NOTE: This is NOT the function for general table updates. See
|
||||
# update_table_definitions for that. This is only for the fielddefs table.
|
||||
sub update_fielddefs_definition {
|
||||
sub update_fielddefs_definition
|
||||
{
|
||||
my $dbh = Bugzilla->dbh;
|
||||
|
||||
# 2005-02-21 - LpSolit@gmail.com - Bug 279910
|
||||
|
@ -46,61 +47,50 @@ sub update_fielddefs_definition {
|
|||
# table should therefore be marked as obsolete, meaning that they cannot
|
||||
# be used anymore when querying the database - they are not deleted in
|
||||
# order to keep track of these fields in the activity table.
|
||||
if (!$dbh->bz_column_info('fielddefs', 'obsolete')) {
|
||||
$dbh->bz_add_column('fielddefs', 'obsolete',
|
||||
{TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'});
|
||||
print "Marking qacontact_accessible and assignee_accessible as",
|
||||
" obsolete fields...\n";
|
||||
$dbh->do("UPDATE fielddefs SET obsolete = 1
|
||||
WHERE name = 'qacontact_accessible'
|
||||
OR name = 'assignee_accessible'");
|
||||
if (!$dbh->bz_column_info('fielddefs', 'obsolete'))
|
||||
{
|
||||
$dbh->bz_add_column('fielddefs', 'obsolete');
|
||||
print "Marking qacontact_accessible and assignee_accessible as obsolete fields...\n";
|
||||
$dbh->do("UPDATE fielddefs SET obsolete=1 WHERE name IN ('qacontact_accessible', 'assignee_accessible')");
|
||||
}
|
||||
|
||||
# 2005-08-10 Myk Melez <myk@mozilla.org> bug 287325
|
||||
# Record each field's type and whether or not it's a custom field,
|
||||
# in fielddefs.
|
||||
$dbh->bz_add_column('fielddefs', 'type',
|
||||
{TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0});
|
||||
$dbh->bz_add_column('fielddefs', 'custom',
|
||||
{TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'});
|
||||
|
||||
# Change the name of the fieldid column to id, so that fielddefs
|
||||
# can use Bugzilla::Object easily. We have to do this up here, because
|
||||
# otherwise adding these field definitions will fail.
|
||||
$dbh->bz_rename_column('fielddefs', 'fieldid', 'id');
|
||||
|
||||
# 2005-08-10 Myk Melez <myk@mozilla.org> bug 287325
|
||||
# Record each field's type and whether or not it's a custom field,
|
||||
# in fielddefs.
|
||||
|
||||
# Add columns that don't require special logic
|
||||
for my $c (qw(type custom clone_bug url is_mandatory add_to_deps default_value
|
||||
visibility_field_id value_field_id))
|
||||
{
|
||||
$dbh->bz_add_column('fielddefs', $c);
|
||||
}
|
||||
$dbh->bz_add_index('fielddefs', 'fielddefs_value_field_id_idx', ['value_field_id']);
|
||||
|
||||
# If the largest fielddefs sortkey is less than 100, then
|
||||
# we're using the old sorting system, and we should convert
|
||||
# it to the new one before adding any new definitions.
|
||||
if (!$dbh->selectrow_arrayref(
|
||||
'SELECT COUNT(id) FROM fielddefs WHERE sortkey >= 100'))
|
||||
if (!$dbh->selectrow_arrayref('SELECT COUNT(id) FROM fielddefs WHERE sortkey >= 100'))
|
||||
{
|
||||
print "Updating the sortkeys for the fielddefs table...\n";
|
||||
my $field_ids = $dbh->selectcol_arrayref(
|
||||
'SELECT id FROM fielddefs ORDER BY sortkey');
|
||||
my $field_ids = $dbh->selectcol_arrayref('SELECT id FROM fielddefs ORDER BY sortkey');
|
||||
my $sortkey = 100;
|
||||
foreach my $field_id (@$field_ids) {
|
||||
$dbh->do('UPDATE fielddefs SET sortkey = ? WHERE id = ?',
|
||||
undef, $sortkey, $field_id);
|
||||
foreach my $field_id (@$field_ids)
|
||||
{
|
||||
$dbh->do('UPDATE fielddefs SET sortkey = ? WHERE id = ?', undef, $sortkey, $field_id);
|
||||
$sortkey += 100;
|
||||
}
|
||||
}
|
||||
|
||||
$dbh->bz_add_column('fielddefs', 'visibility_field_id', {TYPE => 'INT4'});
|
||||
# visibility_value_id is not added anymore during update - it's now in fieldvaluecontrol
|
||||
$dbh->bz_add_column('fielddefs', 'value_field_id', {TYPE => 'INT4'});
|
||||
$dbh->bz_add_index('fielddefs', 'fielddefs_value_field_id_idx',
|
||||
['value_field_id']);
|
||||
|
||||
$dbh->bz_add_column('fielddefs', clone_bug => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 1});
|
||||
$dbh->bz_add_column('fielddefs', url => {TYPE => 'VARCHAR(255)'});
|
||||
$dbh->bz_add_column('fielddefs', is_mandatory => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'});
|
||||
if ($dbh->bz_column_info('fielddefs', 'nullable'))
|
||||
{
|
||||
$dbh->do('UPDATE fielddefs SET is_mandatory=NOT nullable');
|
||||
$dbh->bz_drop_column('fielddefs', 'nullable');
|
||||
}
|
||||
$dbh->bz_add_column('fielddefs', add_to_deps => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0});
|
||||
|
||||
if (!$dbh->bz_column_info('fielddefs', 'delta_ts'))
|
||||
{
|
||||
|
@ -804,20 +794,25 @@ WHERE description LIKE\'%[CC:%\'');
|
|||
$dbh->do('UPDATE bug_status SET is_assigned=0 WHERE NOT value=?', undef, 'ASSIGNED');
|
||||
$dbh->do('UPDATE bug_status SET is_confirmed=0 WHERE value=?', undef, 'UNCONFIRMED');
|
||||
|
||||
# Copy products.defaultmilestone information into fieldvaluecontrol
|
||||
my $fid = Bugzilla->get_field('target_milestone')->id;
|
||||
if ($fid && $dbh->selectrow_array(
|
||||
"SELECT defaultmilestone FROM products p, fieldvaluecontrol c".
|
||||
" WHERE c.field_id=$fid AND c.value_id=p.defaultmilestone".
|
||||
" AND c.visibility_value_id=p.id AND NOT c.is_default"
|
||||
))
|
||||
# Move fieldvaluecontrol.is_default to field_defaults
|
||||
if ($dbh->bz_column_info(fieldvaluecontrol => 'is_default'))
|
||||
{
|
||||
print "Copying default milestone information into fieldvaluecontrol table...\n";
|
||||
$dbh->do("UPDATE fieldvaluecontrol c SET c.is_default=0 WHERE c.field_id=$fid AND c.value_id!=0");
|
||||
$dbh->do(
|
||||
"UPDATE fieldvaluecontrol c, products p SET c.is_default=1".
|
||||
" WHERE c.field_id=$fid AND c.value_id=p.defaultmilestone".
|
||||
" AND c.visibility_value_id=p.id AND NOT c.is_default"
|
||||
"INSERT INTO field_defaults (field_id, visibility_value_id, default_value)".
|
||||
" SELECT field_id, visibility_value_id, ".$dbh->sql_group_concat('value_id', "','").
|
||||
" FROM fieldvaluecontrol WHERE is_default=1"
|
||||
);
|
||||
$dbh->bz_drop_column(fieldvaluecontrol => 'is_default');
|
||||
}
|
||||
|
||||
# Copy products.defaultmilestone information into field_defaults
|
||||
my $fid = Bugzilla->get_field('target_milestone')->id;
|
||||
if ($fid && $dbh->selectrow_array("SELECT * FROM field_defaults WHERE field_id=$fid"))
|
||||
{
|
||||
print "Copying default milestone information into field_defaults...\n";
|
||||
$dbh->do(
|
||||
"INSERT INTO field_defaults (field_id, visibility_value_id, default_value)".
|
||||
" SELECT $fid, id, defaultmilestone FROM products"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3882,9 +3877,6 @@ sub _make_fieldvaluecontrol
|
|||
{
|
||||
my ($dbh) = @_;
|
||||
|
||||
# Dependent default values for custom fields (CustIS Bug 91153)
|
||||
$dbh->bz_add_column('fieldvaluecontrol', is_default => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0});
|
||||
|
||||
if ($dbh->bz_column_info('fielddefs', 'visibility_value_id'))
|
||||
{
|
||||
# Move 3.x visibility_value_id of standard fields to fieldvaluecontrol
|
||||
|
|
|
@ -106,12 +106,13 @@ elsif ($action eq 'update')
|
|||
my $field = Bugzilla->get_field($name);
|
||||
$field || ThrowUserError('customfield_nonexistent', {'name' => $name});
|
||||
|
||||
$field->set_description($cgi->param('desc'));
|
||||
$field->set_sortkey($cgi->param('sortkey'));
|
||||
$field->set_in_new_bugmail($cgi->param('new_bugmail'));
|
||||
$field->set_obsolete($cgi->param('obsolete'));
|
||||
$field->set_description(scalar $cgi->param('desc'));
|
||||
$field->set_sortkey(scalar $cgi->param('sortkey'));
|
||||
$field->set_in_new_bugmail(scalar $cgi->param('new_bugmail'));
|
||||
$field->set_obsolete(scalar $cgi->param('obsolete'));
|
||||
$field->set_is_mandatory(!scalar $cgi->param('nullable'));
|
||||
$field->set_url($cgi->param('url'));
|
||||
$field->set_url(scalar $cgi->param('url'));
|
||||
$field->set_default_value($field->type == FIELD_TYPE_MULTI_SELECT ? [ $cgi->param('default_value') ] : scalar $cgi->param('default_value'));
|
||||
if ($field->custom)
|
||||
{
|
||||
# TODO enter_bug could be edited for non-custom fields, too.
|
||||
|
|
|
@ -126,14 +126,17 @@ if ($action eq 'control_list')
|
|||
|
||||
my $step = $ARGS->{step} || 0;
|
||||
my $visibility_value_id = $ARGS->{visibility_value_id};
|
||||
$visibility_value_id = Bugzilla::Field::Choice->type($field->value_field)->new($visibility_value_id)->{id};
|
||||
|
||||
my $values = $ARGS->{values};
|
||||
my $default_value_id = $ARGS->{default_value_id};
|
||||
my $need_token = 0;
|
||||
|
||||
$vars->{visibility_value_id} = -1;
|
||||
if ($visibility_value_id)
|
||||
{
|
||||
$vars->{visibility_value_id} = $visibility_value_id;
|
||||
$vars->{default_value_hash} = { map { $_ => 1 } split /,/, Bugzilla->fieldvaluecontrol
|
||||
->{$field->value_field_id}->{defaults}->{$field->id}->{$visibility_value_id} };
|
||||
my %values = map { $_->{id} => $_ } @{$field->{value_field}->legal_values()};
|
||||
$vars->{field_value} = $values{$visibility_value_id};
|
||||
$step++ unless $token;
|
||||
|
@ -141,7 +144,10 @@ if ($action eq 'control_list')
|
|||
if ($token)
|
||||
{
|
||||
check_token_data($token, "edit_control_list");
|
||||
$field->update_controlled_values($values, $visibility_value_id, $default_value_id);
|
||||
$field->update_controlled_values($values, $visibility_value_id);
|
||||
$field->update_default_values($visibility_value_id, $field->type == FIELD_TYPE_MULTI_SELECT
|
||||
? [ $cgi->param('default_value') ]
|
||||
: scalar $cgi->param('default_value'));
|
||||
$step++;
|
||||
$need_token = 0;
|
||||
delete_token($token);
|
||||
|
|
|
@ -43,26 +43,27 @@ function initControllerField(i)
|
|||
}
|
||||
|
||||
// Select default value in each controlled field
|
||||
for (var controlled_id in show_fields[f.id]['values'])
|
||||
for (var controlled_id in show_fields[f.id]['defaults'])
|
||||
{
|
||||
var controlled = document.getElementById(controlled_id);
|
||||
if (!controlled)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var vals = show_fields[f.id]['values'][controlled_id];
|
||||
for (var value_id in vals)
|
||||
var v = show_fields[f.id]['defaults'][controlled_id];
|
||||
if (controlled.nodeName == 'SELECT')
|
||||
{
|
||||
if (!vals[value_id][control_id])
|
||||
for (var i in v)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (vals[value_id][control_id].is_default == 1)
|
||||
{
|
||||
document.getElementById('v' + value_id + '_' + controlled_id).selected = true;
|
||||
i = document.getElementById('v' + v[i] + '_' + controlled_id);
|
||||
if (i)
|
||||
i.selected = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
controlled.value = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
handleControllerField(document.forms['Create'] ? null : 'INITIAL', f);
|
||||
|
|
|
@ -113,6 +113,21 @@ var constants = {
|
|||
</select>
|
||||
[% END %]
|
||||
</td>
|
||||
[% IF field.id %]
|
||||
<th align="left" id="default_value_th">Default value:</th>
|
||||
<td id="default_value_td">
|
||||
[% IF field.is_select %]
|
||||
<select name="default_value" style="width: 400px" [% "multiple size=3" IF field.type == constants.FIELD_TYPE_MULTI_SELECT %]>
|
||||
<option value="">---</option>
|
||||
[% FOREACH v = field.legal_values %]
|
||||
<option value="[% v.id | html %]"[% " selected" IF field.default_value_hash.${v.id} %]>[% v.name | html %]</option>
|
||||
[% END %]
|
||||
</select>
|
||||
[% ELSE %]
|
||||
<input type="text" name="default_value" value="[% field.default_value | html %]" style="width: 400px" />
|
||||
[% END %]
|
||||
</td>
|
||||
[% END %]
|
||||
</tr>
|
||||
[% IF field.type && field.type != constants.FIELD_TYPE_BUG_ID_REV || !field.id %]
|
||||
<tr valign="top">
|
||||
|
|
|
@ -37,12 +37,23 @@
|
|||
<input type="hidden" name="step" value="[% step FILTER html %]"/>
|
||||
<input type="hidden" name="visibility_value_id" value="[% visibility_value_id FILTER html %]"/>
|
||||
<p>Значения <strong>[% field.description FILTER html %]</strong> для <strong>[% field_value.name FILTER html %]</strong>:</p>
|
||||
<p>Значение по умолчанию:[% "<br />" IF field.type == constants.FIELD_TYPE_MULTI_SELECT %]
|
||||
[% IF field.is_select %]
|
||||
<select name="default_value" style="width: 400px" [% "multiple size=3" IF field.type == constants.FIELD_TYPE_MULTI_SELECT %]>
|
||||
<option value="">---</option>
|
||||
[% FOREACH v = field.legal_values %]
|
||||
<option value="[% v.id | html %]"[% " selected" IF default_value_hash.${v.id} %]>[% v.name | html %]</option>
|
||||
[% END %]
|
||||
</select>
|
||||
</p>
|
||||
[% ELSE %]
|
||||
<input type="text" name="default_value" value="[% field.default_value | html %]" style="width: 400px" />
|
||||
[% END %]
|
||||
<table id="admin_table" cellpadding="4">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th align="left">Значение</th>
|
||||
<th align="left">Активно</th>
|
||||
<th align="left">По умолчанию</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
[% count = 0 %]
|
||||
|
@ -60,11 +71,6 @@
|
|||
<input type="checkbox" id="val_[% value.id %]" value="[% value.id %]" name="values[]" onchange="changeDefaultEnabling(this);"[% ' checked="checked"' IF value.has_visibility_value(field_value.id, 0) %]/>
|
||||
[% END %]
|
||||
</td>
|
||||
<td align="center">
|
||||
<input type="[% (field.type == constants.FIELD_TYPE_MULTI_SELECT ? 'checkbox' : 'radio') %]"
|
||||
id="def_val_[% value.id %]" value="[% value.id %]"
|
||||
name="default_value_id[]"[% ' checked="checked"' IF value.is_default_controlled_value(field_value.id, 0) %]/>
|
||||
</td>
|
||||
<td>
|
||||
[% IF value.visible_for_all() %]
|
||||
Значение видимо для всех значений поля <strong>[% field.value_field.description FILTER html %]</strong><br/>
|
||||
|
@ -92,37 +98,5 @@
|
|||
<a href="editvalues.cgi?field=
|
||||
[%- field.name FILTER url_quote %]">К списку значений <strong>[% field.description FILTER html %]</strong></a>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
function clearDefault()
|
||||
{
|
||||
var elems = document.forms['setValuesForm'].elements['default_value_id'];
|
||||
for (var i in elems)
|
||||
{
|
||||
elems[i].checked = false;
|
||||
}
|
||||
}
|
||||
function changeDefaultEnabling(self)
|
||||
{
|
||||
var id = self.id.substr('val_'.length);
|
||||
var elem = document.getElementById('def_val_' + id);
|
||||
if (elem)
|
||||
{
|
||||
if ((elem.disabled = !self.checked) && elem.checked)
|
||||
{
|
||||
elem.checked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var checkboxes = document.forms['setValuesForm'].elements['values[]'];
|
||||
for (var i in checkboxes)
|
||||
{
|
||||
if (!checkboxes[i].tagName) continue;
|
||||
if (checkboxes[i].tagName.toLowerCase() != 'input') continue;
|
||||
changeDefaultEnabling(checkboxes[i]);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
[% PROCESS global/footer.html.tmpl %]
|
||||
|
|
Loading…
Reference in New Issue