2013-11-18 17:18:27 +04:00
|
|
|
#!/usr/bin/perl -wT
|
|
|
|
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
|
|
|
#
|
2013-12-20 18:17:15 +04:00
|
|
|
# Page of editinig visibility of custom fields.
|
|
|
|
# License: Dual-license GPL 3.0+ or MPL 1.1+
|
|
|
|
# Contributor(s): Vladimir Koptev <vladimir.koptev@gmail.com>
|
2013-11-18 17:18:27 +04:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
use lib qw(. lib);
|
|
|
|
|
|
|
|
use Bugzilla;
|
|
|
|
use Bugzilla::Constants;
|
|
|
|
use Bugzilla::Util;
|
|
|
|
use Bugzilla::Error;
|
|
|
|
use Bugzilla::User;
|
|
|
|
use Bugzilla::Field;
|
|
|
|
use Bugzilla::Field::Choice;
|
|
|
|
use Bugzilla::Token;
|
|
|
|
|
|
|
|
my $cgi = Bugzilla->cgi;
|
|
|
|
my $template = Bugzilla->template;
|
|
|
|
my $vars = {};
|
|
|
|
# There is only one section about components in the documentation,
|
|
|
|
# so all actions point to the same page.
|
|
|
|
$vars->{'doc_section'} = 'visibility-list.html';
|
|
|
|
|
|
|
|
#
|
|
|
|
# Preliminary checks:
|
|
|
|
#
|
|
|
|
my $user = Bugzilla->login(LOGIN_REQUIRED);
|
2013-12-20 18:17:15 +04:00
|
|
|
$user->in_group('editfields')
|
2013-11-18 17:18:27 +04:00
|
|
|
|| scalar(@{$user->get_editable_products})
|
2013-12-20 18:17:15 +04:00
|
|
|
|| ThrowUserError("auth_failure", {group => "admin",
|
2013-11-18 17:18:27 +04:00
|
|
|
action => "edit",
|
2013-12-20 18:17:15 +04:00
|
|
|
object => "custom_fields"});
|
2013-11-18 17:18:27 +04:00
|
|
|
|
|
|
|
#
|
|
|
|
# often used variables
|
|
|
|
#
|
|
|
|
my $field_name = trim($cgi->param('field') || '');
|
|
|
|
my $value_name = trim($cgi->param('value') || '');
|
|
|
|
my $action = trim($cgi->param('action') || '');
|
|
|
|
my $token = $cgi->param('token');
|
|
|
|
|
|
|
|
unless ($field_name) {
|
|
|
|
ThrowUserError('no_valid_field', {'field' => "field"});
|
|
|
|
}
|
|
|
|
|
|
|
|
my $field = Bugzilla->get_field($field_name);
|
|
|
|
ThrowUserError('no_valid_field', {'field' => "field"}) unless $field;
|
|
|
|
|
|
|
|
my $value = Bugzilla::Field::Choice->type($field)->check($value_name);
|
|
|
|
ThrowUserError('no_valid_value', {'field' => "value"}) unless $value;
|
|
|
|
|
|
|
|
#
|
2013-12-20 18:17:15 +04:00
|
|
|
# action='' -> Show list of custom fields
|
2013-11-18 17:18:27 +04:00
|
|
|
#
|
|
|
|
unless ($action) {
|
|
|
|
$vars->{'field'} = $field;
|
|
|
|
$vars->{'value'} = $value;
|
2013-12-20 18:17:15 +04:00
|
|
|
# controlled fields
|
2013-11-18 17:18:27 +04:00
|
|
|
my $controlled_fields = { map { $_->id => $_ } values $field->controls_visibility_of() };
|
2013-12-20 18:17:15 +04:00
|
|
|
# all custom fields
|
2013-11-18 17:18:27 +04:00
|
|
|
my @fields = Bugzilla->get_fields({custom => 1, sort => 1});
|
2013-12-20 18:17:15 +04:00
|
|
|
# except fields that controls this
|
2013-11-18 17:18:27 +04:00
|
|
|
my $except_fields = { map { $_->id => { map { $_->id => 1 } values $_->controls_visibility_of } } @fields };
|
2013-12-20 18:17:15 +04:00
|
|
|
# fields list
|
2013-12-11 16:51:24 +04:00
|
|
|
my $fields_visibility = {
|
2013-11-18 17:18:27 +04:00
|
|
|
map {
|
2013-12-11 16:51:24 +04:00
|
|
|
$_->id => {
|
2013-11-18 17:18:27 +04:00
|
|
|
id => $_->id,
|
|
|
|
name => $_->name,
|
|
|
|
description => $_->description,
|
2013-12-23 16:38:21 +04:00
|
|
|
visible => $controlled_fields->{$_->id} ? $controlled_fields->{$_->id}->has_visibility_value($value) : 1,
|
|
|
|
visible_for_all => $controlled_fields->{$_->id} ? 0 : 1
|
2013-11-18 17:18:27 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
grep { $_->id ne $field->id && !($except_fields->{$_->id}->{$field->id}) } @fields
|
2013-12-11 16:51:24 +04:00
|
|
|
};
|
2013-12-20 18:17:15 +04:00
|
|
|
#check visible for all fields
|
2013-12-11 16:51:24 +04:00
|
|
|
for my $cfield (@fields)
|
|
|
|
{
|
2013-12-20 18:17:15 +04:00
|
|
|
# first check is not current field and not controlled
|
2013-12-11 16:51:24 +04:00
|
|
|
my $visible_for_all = $cfield->id ne $field->id && !($except_fields->{$field->id}->{$cfield->id});
|
2013-12-23 16:06:45 +04:00
|
|
|
if ($visible_for_all && $controlled_fields->{$cfield->id})
|
|
|
|
{
|
|
|
|
$visible_for_all &&= !$controlled_fields->{$cfield->id}->visibility_values;
|
|
|
|
}
|
2013-12-11 16:51:24 +04:00
|
|
|
if ($visible_for_all)
|
|
|
|
{
|
2013-12-20 18:17:15 +04:00
|
|
|
# check visible for all values
|
2013-12-11 16:51:24 +04:00
|
|
|
for my $cvalue (@{$cfield->legal_values})
|
|
|
|
{
|
|
|
|
next if $cvalue->is_static;
|
|
|
|
if (!$cvalue->visible_for_all(1))
|
|
|
|
{
|
|
|
|
$visible_for_all = 0;
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($visible_for_all)
|
|
|
|
{
|
2013-12-20 18:17:15 +04:00
|
|
|
# realy visible for all
|
|
|
|
# if exists set visibility else push
|
2013-12-11 16:51:24 +04:00
|
|
|
if ($fields_visibility->{$cfield->id})
|
|
|
|
{
|
|
|
|
$fields_visibility->{$cfield->id}->{visible_for_all} = 1;
|
|
|
|
$fields_visibility->{$cfield->id}->{visible} = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
push $vars->{'fields'}, {
|
|
|
|
id => $cfield->id,
|
|
|
|
name => $cfield->name,
|
|
|
|
description => $cfield->description,
|
|
|
|
visible_for_all => 1
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-12-23 16:06:45 +04:00
|
|
|
$vars->{'fields'} = [sort {$a->{description} cmp $b->{description}} values $fields_visibility];
|
2013-11-18 17:18:27 +04:00
|
|
|
$vars->{'token'} = issue_session_token('change_visibility');
|
|
|
|
$template->process("admin/fieldvalues/visibility-list.html.tmpl", $vars)
|
|
|
|
|| ThrowTemplateError($template->error());
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2013-12-20 18:17:15 +04:00
|
|
|
# update result page
|
2013-11-19 17:16:41 +04:00
|
|
|
if ($action eq 'update' && $token) {
|
|
|
|
check_token_data($token, 'change_visibility');
|
2013-11-18 17:18:27 +04:00
|
|
|
|
|
|
|
my @fields = $cgi->param('fields[]');
|
|
|
|
my $controlled_fields = { map { $_->id => $_ } values $field->controls_visibility_of() };
|
|
|
|
my $length = @fields;
|
2013-11-27 14:18:02 +04:00
|
|
|
my $to_update;
|
2013-12-20 18:17:15 +04:00
|
|
|
# if somthing checked
|
2013-11-18 17:18:27 +04:00
|
|
|
if ($length) {
|
2013-12-20 18:17:15 +04:00
|
|
|
# for each checked
|
2013-11-18 17:18:27 +04:00
|
|
|
for my $field_id (@fields) {
|
|
|
|
my $cfield = Bugzilla->get_field($field_id);
|
|
|
|
my $changed = 0;
|
2013-12-11 16:51:24 +04:00
|
|
|
# set VISIBILITY field
|
|
|
|
if ($cfield->visibility_field_id ne $field->id) {
|
2013-11-18 17:18:27 +04:00
|
|
|
$cfield->set_visibility_field($field->id);
|
|
|
|
$changed = 1;
|
|
|
|
}
|
2013-12-11 16:51:24 +04:00
|
|
|
# set VALUE field
|
2013-11-18 17:18:27 +04:00
|
|
|
if ($cfield->value_field_id ne $field->id) {
|
|
|
|
$cfield->set_value_field($field->id);
|
|
|
|
$changed = 1;
|
|
|
|
}
|
2013-12-20 18:17:15 +04:00
|
|
|
# set visibility values
|
2013-11-18 17:18:27 +04:00
|
|
|
my $visibility_values = {map { $_->id=>1 } values ($cfield->visibility_values || [])};
|
|
|
|
if (!$visibility_values->{$value->id}) {
|
|
|
|
$visibility_values->{$value->id} = 1;
|
|
|
|
$cfield->set_visibility_values([keys $visibility_values]);
|
|
|
|
$changed = 1;
|
|
|
|
}
|
2013-12-20 18:17:15 +04:00
|
|
|
# update if something was changed
|
2013-11-18 17:18:27 +04:00
|
|
|
if ($changed) {
|
2013-11-27 14:18:02 +04:00
|
|
|
if (!$to_update->{$cfield->id}) {
|
|
|
|
$to_update->{$cfield->id} = {field => $cfield, actions => {updated => 1}};
|
2013-11-18 17:18:27 +04:00
|
|
|
}
|
|
|
|
}
|
2013-12-20 18:17:15 +04:00
|
|
|
# delete from controlled fields for next checking "visible for all"
|
2013-11-18 17:18:27 +04:00
|
|
|
if ($controlled_fields->{$cfield->id}) {
|
|
|
|
delete $controlled_fields->{$cfield->id};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-12-20 18:17:15 +04:00
|
|
|
|
|
|
|
# make visible for all if it needs
|
2013-11-18 17:18:27 +04:00
|
|
|
for my $cfield (values $controlled_fields) {
|
|
|
|
my $visibility_values = { map { $_->id => 1 } values $cfield->visibility_values};
|
2013-12-11 16:51:24 +04:00
|
|
|
if (!%$visibility_values) {
|
|
|
|
# cfield is visible for all values
|
|
|
|
# get them all!!!
|
|
|
|
$visibility_values = { map { $_->id => 1 } values $cfield->visibility_field->legal_values};
|
|
|
|
}
|
2013-11-18 17:18:27 +04:00
|
|
|
if ($visibility_values->{$value->id}) {
|
|
|
|
delete $visibility_values->{$value->id};
|
|
|
|
$cfield->set_visibility_values([keys $visibility_values]);
|
2013-11-27 14:18:02 +04:00
|
|
|
if (!$to_update->{$cfield->id}) {
|
|
|
|
$to_update->{$cfield->id} = {field => $cfield, actions => {}};
|
2013-11-18 17:18:27 +04:00
|
|
|
}
|
2013-11-27 14:18:02 +04:00
|
|
|
$to_update->{$cfield->id}->{actions}->{cleared} = 1;
|
2013-11-18 17:18:27 +04:00
|
|
|
}
|
|
|
|
if (!%$visibility_values) {
|
|
|
|
$cfield->set_visibility_field(undef);
|
|
|
|
$cfield->set_value_field(undef);
|
2013-11-27 14:18:02 +04:00
|
|
|
if (!$to_update->{$cfield->id}) {
|
|
|
|
$to_update->{$cfield->id} = {field => $cfield, actions => {}};
|
2013-11-18 17:18:27 +04:00
|
|
|
}
|
2013-11-27 14:18:02 +04:00
|
|
|
$to_update->{$cfield->id}->{actions}->{cleared} = 1;
|
2013-11-18 17:18:27 +04:00
|
|
|
}
|
|
|
|
}
|
2013-12-20 18:17:15 +04:00
|
|
|
|
|
|
|
# make lists of updated and cleared fields for view
|
2013-11-18 17:18:27 +04:00
|
|
|
my @updated;
|
|
|
|
my @cleared;
|
2013-11-27 14:18:02 +04:00
|
|
|
for my $cfield (values $to_update) {
|
2013-11-18 17:18:27 +04:00
|
|
|
$cfield->{field}->update();
|
|
|
|
if ($cfield->{actions}->{cleared}) {
|
|
|
|
push @cleared, $cfield->{field}->description;
|
|
|
|
}
|
|
|
|
if ($cfield->{actions}->{updated}) {
|
|
|
|
push @updated, $cfield->{field}->description;
|
|
|
|
}
|
|
|
|
}
|
2013-11-19 17:16:41 +04:00
|
|
|
delete_token($token);
|
2013-11-18 17:18:27 +04:00
|
|
|
|
|
|
|
$vars->{'field'} = $field;
|
|
|
|
$vars->{'value'} = $value;
|
|
|
|
$vars->{'update'} = 1;
|
|
|
|
$vars->{'updated'} = join(', ', @updated);
|
|
|
|
$vars->{'cleared'} = join(', ', @cleared);
|
|
|
|
$template->process("admin/fieldvalues/visibility-list.html.tmpl", $vars)
|
|
|
|
|| ThrowTemplateError($template->error());
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# No valid action found
|
|
|
|
#
|
|
|
|
ThrowUserError('no_valid_action', {'field' => "action"});
|
|
|
|
|
|
|
|
__END__
|