Bug 70168 - Новый вариант RPC API "XMLSimple": принимаются параметры по REST, ответ отдаётся простой сериализацией в XML. Сделал, ибо штатный XML-RPC, провязанный через библиотеки хз-где и хз-как имеет проблемы как минимум с обработкой ошибок.
git-svn-id: svn://svn.office.custis.ru/3rdparty/bugzilla.org/trunk@1018 6955db30-a419-402b-8a0d-67ecbb4d7f56master
parent
6f7b8675dc
commit
6a3df8a015
45
Bugzilla.pm
45
Bugzilla.pm
|
@ -705,6 +705,51 @@ sub get_fields
|
|||
return @fields;
|
||||
}
|
||||
|
||||
# Cache for fieldvaluecontrol table
|
||||
sub fieldvaluecontrol
|
||||
{
|
||||
my $class = shift;
|
||||
if (!$class->request_cache->{fieldvaluecontrol})
|
||||
{
|
||||
$class->request_cache->{fieldvaluecontrol} = $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 (@{$class->request_cache->{fieldvaluecontrol}})
|
||||
{
|
||||
if ($_->{value_id})
|
||||
{
|
||||
$has->{$_->{visibility_field_id}}
|
||||
->{values}
|
||||
->{$_->{field_id}}
|
||||
->{$_->{value_id}}
|
||||
->{$_->{visibility_value_id}} = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$has->{$_->{visibility_field_id}}
|
||||
->{fields}
|
||||
->{$_->{field_id}}
|
||||
->{$_->{visibility_value_id}} = 1;
|
||||
}
|
||||
}
|
||||
$class->request_cache->{fieldvaluecontrol_hash} = $has;
|
||||
}
|
||||
return $class->request_cache->{fieldvaluecontrol};
|
||||
}
|
||||
|
||||
sub fieldvaluecontrol_hash
|
||||
{
|
||||
my $class = shift;
|
||||
if (!$class->request_cache->{fieldvaluecontrol_hash})
|
||||
{
|
||||
$class->fieldvaluecontrol;
|
||||
}
|
||||
return $class->request_cache->{fieldvaluecontrol_hash};
|
||||
}
|
||||
|
||||
sub active_custom_fields
|
||||
{
|
||||
my $class = shift;
|
||||
|
|
|
@ -483,23 +483,33 @@ sub is_select {
|
|||
|| $_[0]->type == FIELD_TYPE_MULTI_SELECT) ? 1 : 0
|
||||
}
|
||||
|
||||
sub legal_values {
|
||||
sub legal_values
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
if (!defined $self->{'legal_values'}) {
|
||||
return [] unless $self->is_select;
|
||||
if (!defined $self->{legal_values})
|
||||
{
|
||||
require Bugzilla::Field::Choice;
|
||||
my @values = Bugzilla::Field::Choice->type($self)->get_all();
|
||||
$self->{'legal_values'} = \@values;
|
||||
$self->{legal_values} = [ Bugzilla::Field::Choice->type($self)->get_all() ];
|
||||
}
|
||||
return $self->{'legal_values'};
|
||||
return $self->{legal_values};
|
||||
}
|
||||
|
||||
sub restricted_legal_values
|
||||
{
|
||||
my $self = shift;
|
||||
my ($controller_value) = @_;
|
||||
return $self->legal_values unless $controller_value;
|
||||
return $controller_value->controlled_plus_generic->{$self->name};
|
||||
return $self->legal_values unless $controller_value && $self->value_field_id;
|
||||
my $cid = $controller_value->id;
|
||||
if (!$self->{restricted_legal_values}->{$cid})
|
||||
{
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash->{$self->value_field_id}->{values}->{$self->id};
|
||||
$self->{restricted_legal_values}->{$cid} = [
|
||||
grep { !exists $hash->{$_->id} || $hash->{$_->id}->{$cid} }
|
||||
@{$self->legal_values}
|
||||
];
|
||||
}
|
||||
return $self->{restricted_legal_values}->{$cid};
|
||||
}
|
||||
|
||||
=pod
|
||||
|
@ -1105,16 +1115,13 @@ Returns: the corresponding field ID or an error if the field name
|
|||
|
||||
=cut
|
||||
|
||||
sub get_field_id {
|
||||
sub get_field_id
|
||||
{
|
||||
my ($name) = @_;
|
||||
my $dbh = Bugzilla->dbh;
|
||||
|
||||
trick_taint($name);
|
||||
my $id = $dbh->selectrow_array('SELECT id FROM fielddefs
|
||||
WHERE name = ?', undef, $name);
|
||||
|
||||
ThrowCodeError('invalid_field_name', {field => $name}) unless $id;
|
||||
return $id
|
||||
my $field = Bugzilla->get_field($name);
|
||||
ThrowCodeError('invalid_field_name', {field => $name}) unless $field;
|
||||
return $field->id;
|
||||
}
|
||||
|
||||
# Shared between Bugzilla::Field and Bugzilla::Field::Choice
|
||||
|
@ -1140,25 +1147,18 @@ sub update_visibility_values
|
|||
}
|
||||
|
||||
# Moved from bug/field-events.js.tmpl
|
||||
# Now uses one pass over cached fieldvaluecontrol table
|
||||
sub json_visibility
|
||||
{
|
||||
my $self = shift;
|
||||
my $show = { fields => {}, values => {} };
|
||||
foreach my $controlled (@{$self->controls_visibility_of})
|
||||
{
|
||||
$show->{fields}->{$controlled->name} = { map { $_->id => 1 } @{$controlled->visibility_values} };
|
||||
}
|
||||
$show->{legal} = [ map { [ $_->id, $_->name ] } @{$self->legal_values} ];
|
||||
foreach my $value (@{$self->legal_values})
|
||||
{
|
||||
foreach my $controlled_field (keys %{$value->controlled_values})
|
||||
{
|
||||
foreach my $controlled_value (@{$value->controlled_values->{$controlled_field}})
|
||||
{
|
||||
$show->{values}->{$controlled_field}->{$controlled_value->id}->{$value->id} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
my $show = {
|
||||
legal => [ map { [ $_->id, $_->name ] } @{$self->legal_values} ],
|
||||
fields => {},
|
||||
values => {},
|
||||
};
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash->{$self->id};
|
||||
$show->{fields} = { map { Bugzilla->get_field($_)->name => $hash->{fields}->{$_} } keys %{$hash->{fields}} };
|
||||
$show->{values} = { map { Bugzilla->get_field($_)->name => $hash->{values}->{$_} } keys %{$hash->{values}} };
|
||||
$show = encode_json($show);
|
||||
Encode::_utf8_on($show);
|
||||
return $show;
|
||||
|
@ -1181,3 +1181,24 @@ showValueWhen['[% field.name | js %]'][[% val.id %]]['[% controlled_field | js %
|
|||
[% END %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
for my $row (@{Bugzilla->fieldvaluecontrol})
|
||||
{
|
||||
$field_name = Bugzilla->get_field($row->{field_id})->name;
|
||||
if ($row->{visibility_field_id} == $self->id)
|
||||
{
|
||||
if ($row->{value_id})
|
||||
{
|
||||
$show->{values}
|
||||
->{$field_name}
|
||||
->{$row->{value_id}}
|
||||
->{$row->{visibility_value_id}} = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$show->{fields}
|
||||
->{$field_name}
|
||||
->{$row->{visibility_value_id}} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ sub remove_from_db {
|
|||
{ field => $self->field, value => $self });
|
||||
}
|
||||
if ($self->bug_count) {
|
||||
ThrowUserError("fieldvalue_still_has_bugs",
|
||||
ThrowUserError('fieldvalue_still_has_bugs',
|
||||
{ field => $self->field, value => $self });
|
||||
}
|
||||
$self->_check_if_controller();
|
||||
|
@ -205,7 +205,7 @@ sub remove_from_db {
|
|||
sub _check_if_controller {
|
||||
my $self = shift;
|
||||
my $vis_fields = $self->controls_visibility_of_fields;
|
||||
my $values = $self->controlled_values;
|
||||
my $values = $self->controls_visibility_of_field_values;
|
||||
if (@$vis_fields || scalar grep { @{$values->{$_}} } keys %$values) {
|
||||
ThrowUserError('fieldvalue_is_controller',
|
||||
{ value => $self, fields => [map($_->name, @$vis_fields)],
|
||||
|
@ -213,7 +213,6 @@ sub _check_if_controller {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#############
|
||||
# Accessors #
|
||||
#############
|
||||
|
@ -276,83 +275,59 @@ sub is_static {
|
|||
sub controls_visibility_of_fields
|
||||
{
|
||||
my $self = shift;
|
||||
my $f;
|
||||
unless ($f = $self->{controls_visibility_of_fields})
|
||||
{
|
||||
$f = Bugzilla->dbh->selectcol_arrayref(
|
||||
"SELECT f.id FROM fielddefs f, fieldvaluecontrol c WHERE c.field_id=f.id".
|
||||
" AND f.visibility_field_id=? AND c.visibility_value_id=? AND c.value_id=0",
|
||||
undef, $self->field->id, $self->id
|
||||
);
|
||||
$_ = Bugzilla->get_field($_) for @$f;
|
||||
$self->{controls_visibility_of_fields} = $f;
|
||||
}
|
||||
return $f;
|
||||
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}
|
||||
];
|
||||
return $self->{controls_visibility_of_fields};
|
||||
}
|
||||
|
||||
sub controlled_values
|
||||
sub controls_visibility_of_field_values
|
||||
{
|
||||
my $self = shift;
|
||||
my $controlled_values;
|
||||
unless ($controlled_values = $self->{controlled_values})
|
||||
my $vid = $self->id;
|
||||
my $fid = $self->field->id;
|
||||
if (!$self->{controls_visibility_of_field_values})
|
||||
{
|
||||
$controlled_values = {};
|
||||
my $fields = $self->field->controls_values_of;
|
||||
foreach my $field (@$fields)
|
||||
my $r = {};
|
||||
for (@{Bugzilla->fieldvaluecontrol})
|
||||
{
|
||||
my $f = Bugzilla->dbh->selectcol_arrayref(
|
||||
"SELECT value_id FROM fieldvaluecontrol WHERE field_id=? AND visibility_value_id=? AND value_id!=0",
|
||||
undef, $field->id, $self->id);
|
||||
if (@$f)
|
||||
if ($_->{value_id} &&
|
||||
$_->{visibility_value_id} == $vid &&
|
||||
$_->{visibility_field_id} == $fid)
|
||||
{
|
||||
my $type = Bugzilla::Field::Choice->type($field);
|
||||
$f = $type->match({ id => $f });
|
||||
push @{$r->{$_->{field_id}}}, $_->{value_id};
|
||||
}
|
||||
$controlled_values->{$field->name} = $f;
|
||||
}
|
||||
$self->{controlled_values} = $controlled_values;
|
||||
$self->{controls_visibility_of_field_values} = { map {
|
||||
Bugzilla->get_field($_)->name =>
|
||||
Bugzilla::Field::Choice->type(Bugzilla->get_field($_))->new_from_list($r->{$_})
|
||||
} keys %$r };
|
||||
}
|
||||
return $controlled_values;
|
||||
}
|
||||
|
||||
sub controlled_plus_generic
|
||||
{
|
||||
my $self = shift;
|
||||
my $controlled_values;
|
||||
unless ($controlled_values = $self->{controlled_plus_generic})
|
||||
{
|
||||
my $fields = $self->field->controls_values_of;
|
||||
foreach my $field (@$fields)
|
||||
{
|
||||
my $f = Bugzilla->dbh->selectcol_arrayref(
|
||||
"SELECT value_id FROM fieldvaluecontrol WHERE field_id=? AND visibility_value_id=? AND value_id!=0
|
||||
UNION ALL SELECT id FROM ".$field->name." f LEFT JOIN fieldvaluecontrol c ON c.value_id=f.id AND c.field_id=? WHERE c.visibility_value_id IS NULL",
|
||||
undef, $field->id, $self->id, $field->id);
|
||||
if (@$f)
|
||||
{
|
||||
my $type = Bugzilla::Field::Choice->type($field);
|
||||
$f = $type->match({ id => $f });
|
||||
}
|
||||
$controlled_values->{$field->name} = $f;
|
||||
}
|
||||
$self->{controlled_plus_generic} = $controlled_values;
|
||||
}
|
||||
return $controlled_values;
|
||||
return $self->{controls_visibility_of_field_values};
|
||||
}
|
||||
|
||||
sub visibility_values
|
||||
{
|
||||
my $self = shift;
|
||||
my $f;
|
||||
if ($self->field->value_field && !($f = $self->{visibility_values}))
|
||||
if ($self->field->value_field_id && !($f = $self->{visibility_values}))
|
||||
{
|
||||
$f = Bugzilla->dbh->selectcol_arrayref(
|
||||
"SELECT visibility_value_id FROM fieldvaluecontrol WHERE field_id=? AND value_id=?",
|
||||
undef, $self->field->id, $self->id);
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash
|
||||
->{$self->field->value_field_id}
|
||||
->{values}
|
||||
->{$self->field->id}
|
||||
->{$self->id};
|
||||
$f = $hash ? [ keys %$hash ] : [];
|
||||
if (@$f)
|
||||
{
|
||||
my $type = Bugzilla::Field::Choice->type($self->field->value_field);
|
||||
$f = $type->match({ id => $f });
|
||||
$f = $type->new_from_list($f);
|
||||
}
|
||||
$self->{visibility_values} = $f;
|
||||
}
|
||||
|
@ -364,8 +339,12 @@ sub has_visibility_value
|
|||
my $self = shift;
|
||||
my ($value) = @_;
|
||||
ref $value and $value = $value->id;
|
||||
my %f = map { $_->id => 1 } @{$self->visibility_values};
|
||||
return $f{$value};
|
||||
return Bugzilla->fieldvaluecontrol_hash
|
||||
->{$self->field->value_field_id}
|
||||
->{values}
|
||||
->{$self->field->id}
|
||||
->{$self->id}
|
||||
->{$value};
|
||||
}
|
||||
|
||||
############
|
||||
|
|
|
@ -48,7 +48,8 @@ use base qw(Exporter);
|
|||
validate_email_syntax clean_text
|
||||
stem_text
|
||||
intersect
|
||||
get_text template_var disable_utf8);
|
||||
get_text template_var disable_utf8
|
||||
xml_element xml_element_quote xml_dump_simple);
|
||||
|
||||
use Bugzilla::Constants;
|
||||
|
||||
|
@ -59,7 +60,7 @@ use DateTime::TimeZone;
|
|||
use Digest;
|
||||
use Email::Address;
|
||||
use List::Util qw(first);
|
||||
use Scalar::Util qw(tainted);
|
||||
use Scalar::Util qw(tainted blessed);
|
||||
use Template::Filters;
|
||||
use Text::Wrap;
|
||||
use Text::TabularDisplay::Utf8;
|
||||
|
@ -760,6 +761,60 @@ sub intersect
|
|||
return $values;
|
||||
}
|
||||
|
||||
sub xml_element_quote
|
||||
{
|
||||
my ($name, $args, $content) = @_;
|
||||
xml_element($name, $args, xml_quote($content));
|
||||
}
|
||||
|
||||
sub xml_element
|
||||
{
|
||||
my ($name, $args, $content) = @_;
|
||||
if (ref $args)
|
||||
{
|
||||
$args = join '', map { ' '.xml_quote($_).'="'.xml_quote($args->{$_}).'"' } keys %$args;
|
||||
}
|
||||
$name = xml_quote($name);
|
||||
$args = '<'.$name.$args;
|
||||
if (defined $content && $content eq '')
|
||||
{
|
||||
return $args.' />';
|
||||
}
|
||||
return $args.'>'.$content.'</'.$name.'>';
|
||||
}
|
||||
|
||||
sub xml_dump_simple
|
||||
{
|
||||
my ($data) = @_;
|
||||
if (ref $data)
|
||||
{
|
||||
my $r;
|
||||
if ($data =~ 'ARRAY')
|
||||
{
|
||||
$r = join '', map { xml_element('i', '', xml_dump_simple($_)) } @$data;
|
||||
}
|
||||
elsif ($data =~ 'HASH')
|
||||
{
|
||||
$r = join '', map { xml_element($_, '', xml_dump_simple($data->{$_})) } keys %$data;
|
||||
}
|
||||
elsif ($data =~ 'SCALAR')
|
||||
{
|
||||
# TODO потенциально можно сохранять ссылки
|
||||
$r = xml_element('ref', '', xml_dump_simple($$data));
|
||||
}
|
||||
else
|
||||
{
|
||||
$r = xml_quote("$data");
|
||||
}
|
||||
if (my $p = blessed($data))
|
||||
{
|
||||
$r = xml_element('object', {class => $p}, $r);
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
return xml_quote("$data");
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
#!/usr/bin/perl
|
||||
# Bugzilla::WebService::Field - API for managing custom fields and values
|
||||
|
||||
package Bugzilla::WebService::Field;
|
||||
|
||||
use strict;
|
||||
use base qw(Bugzilla::WebService);
|
||||
use Bugzilla::Field::Choice;
|
||||
use Bugzilla::User;
|
||||
use Bugzilla::WebService::Util qw(validate);
|
||||
|
||||
# { field => 'имя_поля' }
|
||||
sub get_values
|
||||
{
|
||||
my ($self, $params) = @_;
|
||||
my $field = Bugzilla->get_field($params->{field});
|
||||
if (!$field)
|
||||
{
|
||||
return {status => 'field_not_found'};
|
||||
}
|
||||
if (!$field->is_select)
|
||||
{
|
||||
return {status => 'field_not_select'};
|
||||
}
|
||||
my $values;
|
||||
if ($field->value_field_id)
|
||||
{
|
||||
$values = [ map { {
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
visibility_value_ids => [ map { $_->id } @{$_->visibility_values} ],
|
||||
} } ];
|
||||
}
|
||||
else
|
||||
{
|
||||
$values = [ map { { id => $_->id, name => $_->name } } @{$field->legal_values} ];
|
||||
}
|
||||
return {
|
||||
status => 'ok',
|
||||
values => $values,
|
||||
};
|
||||
}
|
||||
|
||||
# { field => 'имя_поля', value => 'имя_значения', sortkey => число_для_сортировки }
|
||||
sub add_value
|
||||
{
|
||||
my ($self, $params) = @_;
|
||||
my $field = Bugzilla->get_field($params->{field});
|
||||
if (!$field)
|
||||
{
|
||||
return {status => 'field_not_found'};
|
||||
}
|
||||
my $type = Bugzilla::Field::Choice->type($field);
|
||||
my $value = $type->new({ name => $params->{value} });
|
||||
if ($value)
|
||||
{
|
||||
return {status => 'value_already_exists'};
|
||||
}
|
||||
$value = $type->create({
|
||||
value => $params->{value},
|
||||
sortkey => $params->{sortkey},
|
||||
});
|
||||
return {status => 'ok', id => $value->id};
|
||||
}
|
||||
|
||||
# { field => 'имя_поля', old_value => 'имя_значения', new_value => 'новое_имя_значения', sortkey => новый_sortkey }
|
||||
sub update_value
|
||||
{
|
||||
my ($self, $params) = @_;
|
||||
my $field = Bugzilla->get_field($params->{field});
|
||||
if (!$field)
|
||||
{
|
||||
return {status => 'field_not_found'};
|
||||
}
|
||||
my $type = Bugzilla::Field::Choice->type($field);
|
||||
my $value = $type->new({ name => $params->{new_value} });
|
||||
if ($value)
|
||||
{
|
||||
return {status => 'value_already_exists'};
|
||||
}
|
||||
$value = $type->new({ name => $params->{old_value} });
|
||||
if (!$value)
|
||||
{
|
||||
return {status => 'value_not_found'};
|
||||
}
|
||||
$value->set_value($params->{new_value});
|
||||
$value->set_sortkey($params->{sortkey});
|
||||
$value->update;
|
||||
return {status => 'ok', id => $value->id};
|
||||
}
|
||||
|
||||
# { field => 'имя_поля', value => 'имя_значения' }
|
||||
sub delete_value
|
||||
{
|
||||
my ($self, $params) = @_;
|
||||
my $field = Bugzilla->get_field($params->{field});
|
||||
if (!$field)
|
||||
{
|
||||
return {status => 'field_not_found'};
|
||||
}
|
||||
my $type = Bugzilla::Field::Choice->type($field);
|
||||
my $value = $type->new({ name => $params->{value} });
|
||||
if (!$value)
|
||||
{
|
||||
return {status => 'value_not_found'};
|
||||
}
|
||||
$value->remove_from_db;
|
||||
return {status => 'ok'};
|
||||
}
|
||||
|
||||
# { field => 'имя_поля', value => 'имя_значения', ids => [ ID продукта, ID продукта, ... ] }
|
||||
sub set_visibility_values
|
||||
{
|
||||
my ($self, $params) = @_;
|
||||
my $field = Bugzilla->get_field($params->{field});
|
||||
if (!$field)
|
||||
{
|
||||
return {status => 'field_not_found'};
|
||||
}
|
||||
my $type = Bugzilla::Field::Choice->type($field);
|
||||
my $value = $type->new({ name => $params->{value} });
|
||||
if (!$value)
|
||||
{
|
||||
return {status => 'value_not_found'};
|
||||
}
|
||||
$type->set_visibility_values($params->{ids});
|
||||
return {status => 'ok'};
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
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): Vitaliy Filippov <vitalif@mail.ru>
|
|
@ -44,17 +44,40 @@ sub get_accessible_products {
|
|||
return {ids => [map {$_->id} @{Bugzilla->user->get_accessible_products}]};
|
||||
}
|
||||
|
||||
# Get the list of product IDs by classification name
|
||||
sub get_products_by_classification
|
||||
{
|
||||
my ($self, $params) = @_;
|
||||
if (!Bugzilla->params->{useclassification})
|
||||
{
|
||||
return {status => 'classification_is_off'};
|
||||
}
|
||||
my $cid = $params->{classification};
|
||||
if (!$cid)
|
||||
{
|
||||
return {status => 'classification_not_specified'};
|
||||
}
|
||||
$cid = Bugzilla::Classification->check($cid)->id;
|
||||
return {
|
||||
ids => [
|
||||
map { $_->id }
|
||||
grep { $_->classification_id eq $cid }
|
||||
@{ Bugzilla->user->get_enterable_products }
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
# Get a list of actual products, based on list of ids
|
||||
sub get {
|
||||
my ($self, $params) = validate(@_, 'ids');
|
||||
|
||||
# Only products that are in the users accessible products,
|
||||
|
||||
# Only products that are in the users <s>accessible</s> enterable products,
|
||||
# can be allowed to be returned
|
||||
my $accessible_products = Bugzilla->user->get_accessible_products;
|
||||
my $accessible_products = Bugzilla->user->get_enterable_products;
|
||||
|
||||
# Create a hash with the ids the user wants
|
||||
my %ids = map { $_ => 1 } @{$params->{ids}};
|
||||
|
||||
|
||||
# Return the intersection of this, by grepping the ids from
|
||||
# accessible products.
|
||||
my @requested_accessible = grep { $ids{$_->id} } @$accessible_products;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
package Bugzilla::WebService::Server::XMLSimple;
|
||||
|
||||
use strict;
|
||||
|
||||
sub type { $_[2] }
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -63,7 +63,6 @@
|
|||
|
||||
[% IF value.is_default || value.bug_count || (value_count == 1)
|
||||
|| value.controls_visibility_of_fields.size
|
||||
|| value.controlled_values_array.size
|
||||
%]
|
||||
|
||||
<p>Sorry, but the '[% value.name FILTER html %]' value cannot be deleted
|
||||
|
@ -115,25 +114,22 @@
|
|||
[% IF value.controls_visibility_of_fields.size %]
|
||||
<li>This value controls the visibility of the following fields:<br>
|
||||
[% FOREACH field = value.controls_visibility_of_fields %]
|
||||
<a href="editfields.cgi?action=edit&name=
|
||||
[%- field.name FILTER url_quote %]">
|
||||
[%- field.description FILTER html %]
|
||||
([% field.name FILTER html %])</a><br>
|
||||
<a href="editfields.cgi?action=edit&name=[% field.name | url_quote %]">
|
||||
[%- field.description | html %]
|
||||
([% field.name | html %])</a><br>
|
||||
[% END %]
|
||||
</li>
|
||||
[% END %]
|
||||
|
||||
[% IF value.controlled_values_array.size %]
|
||||
[% IF value.controls_visibility_of_field_values %]
|
||||
<li>This value controls the visibility of the following values in
|
||||
other fields:<br>
|
||||
[% FOREACH field_name = value.controlled_values.keys %]
|
||||
[% FOREACH controlled = value.controlled_values.${field_name} %]
|
||||
<a href="editvalues.cgi?action=edit&field=
|
||||
[%- controlled.field.name FILTER url_quote %]&value=
|
||||
[%- controlled.name FILTER url_quote %]">
|
||||
[% controlled.field.description FILTER html %]
|
||||
([% controlled.field.name FILTER html %]):
|
||||
[%+ controlled.name FILTER html %]</a><br>
|
||||
[% FOREACH field_name = value.controls_visibility_of_field_values.keys %]
|
||||
[% FOREACH controlled = value.controls_visibility_of_field_values.${field_name} %]
|
||||
<a href="editvalues.cgi?action=edit&field=[% field_name | url_quote %]&value=[% controlled.name | url_quote %]">
|
||||
[% controlled.field.description | html %]
|
||||
([% controlled.field.name | html %]):
|
||||
[%+ controlled.name | html %]</a><br>
|
||||
[% END %]
|
||||
[% END %]
|
||||
</li>
|
||||
|
|
93
xml.cgi
93
xml.cgi
|
@ -26,16 +26,97 @@ use strict;
|
|||
|
||||
use lib qw(. lib);
|
||||
use Bugzilla;
|
||||
use Bugzilla::Constants;
|
||||
use Bugzilla::Util;
|
||||
use Bugzilla::WebService::Server::XMLSimple;
|
||||
|
||||
my $cgi = Bugzilla->cgi;
|
||||
|
||||
# Convert comma/space separated elements into separate params
|
||||
my @ids = ();
|
||||
my $args = $cgi->Vars;
|
||||
my $method = $args->{method};
|
||||
|
||||
if (defined $cgi->param('id')) {
|
||||
@ids = split (/[, ]+/, $cgi->param('id'));
|
||||
sub addmsg
|
||||
{
|
||||
my ($result, $message) = @_;
|
||||
if (ref $message && $message->isa('Bugzilla::Error'))
|
||||
{
|
||||
$result->{status} = $message->{error};
|
||||
$result->{error_data} = $message->{vars};
|
||||
delete $message->{vars}->{error};
|
||||
}
|
||||
else
|
||||
{
|
||||
$result->{message} = "$message";
|
||||
}
|
||||
}
|
||||
|
||||
my $ids = join('', map { $_ = "&id=" . $_ } @ids);
|
||||
if (!$method)
|
||||
{
|
||||
# Backward compatibility: redirect to show_bug.cgi?ctype=xml
|
||||
# Convert comma/space separated elements into separate params
|
||||
my @ids = ();
|
||||
|
||||
print $cgi->redirect("show_bug.cgi?ctype=xml$ids");
|
||||
if (defined $cgi->param('id')) {
|
||||
@ids = split (/[, ]+/, $cgi->param('id'));
|
||||
}
|
||||
|
||||
my $ids = join('', map { $_ = "&id=" . $_ } @ids);
|
||||
|
||||
print $cgi->redirect("show_bug.cgi?ctype=xml$ids");
|
||||
}
|
||||
else
|
||||
{
|
||||
# Very simple "REST/XML-RPC" server:
|
||||
# Takes arguments from GET and POST parameters, returns XML.
|
||||
Bugzilla->error_mode(ERROR_MODE_DIE);
|
||||
Bugzilla->login;
|
||||
my ($service, $result);
|
||||
($service, $method) = split /\./, $method;
|
||||
$service =~ s/[^a-z0-9]+//giso;
|
||||
if (!$Bugzilla::WebService::{$service.'::'} ||
|
||||
!$Bugzilla::WebService::{$service.'::'}->{'XMLSimple::'})
|
||||
{
|
||||
eval { require "Bugzilla/WebService/$service.pm" };
|
||||
if ($@)
|
||||
{
|
||||
$result = {
|
||||
status => 'bad_service',
|
||||
service => $service,
|
||||
method => $method,
|
||||
};
|
||||
addmsg($result, $@);
|
||||
}
|
||||
else
|
||||
{
|
||||
# This perversion is needed to override Bugzilla::WebService->type() method
|
||||
eval "\@Bugzilla::WebService::$service\::XMLSimple::ISA = qw(Bugzilla::WebService::Server::XMLSimple Bugzilla::WebService::$service)";
|
||||
}
|
||||
}
|
||||
if ($Bugzilla::WebService::{$service.'::'} &&
|
||||
$Bugzilla::WebService::{$service.'::'}->{'XMLSimple::'})
|
||||
{
|
||||
my $func_args = { %$args };
|
||||
delete $func_args->{method};
|
||||
my $pkg = 'Bugzilla::WebService::'.$service.'::XMLSimple';
|
||||
eval { $result = $pkg->$method($func_args) };
|
||||
if ($@)
|
||||
{
|
||||
$result = {
|
||||
status => 'error',
|
||||
service => $service,
|
||||
method => $method,
|
||||
};
|
||||
addmsg($result, $@);
|
||||
}
|
||||
else
|
||||
{
|
||||
$result->{status} ||= 'ok';
|
||||
}
|
||||
}
|
||||
# Send response
|
||||
Bugzilla->send_header(-type => 'text/xml'.(Bugzilla->params->{utf8} ? '; charset=utf-8' : ''));
|
||||
print '<?xml version="1.0"'.(Bugzilla->params->{utf8} ? ' encoding="UTF-8"' : '').' ?>';
|
||||
print '<response>';
|
||||
print xml_dump_simple($result);
|
||||
print '</response>';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue