Commit 32a5f448 authored by Byron Jones's avatar Byron Jones

Bug 655229: Adds components, versions and milestones to Product.get

r=mkanat, a=mkanat
parent cca5b123
......@@ -175,8 +175,9 @@ sub _legal_field_values {
my $product_name = $value->product->name;
if ($user->can_see_product($product_name)) {
push(@result, {
name => $self->type('string', $value->name),
sortkey => $self->type('int', $sortkey),
name => $self->type('string', $value->name),
sort_key => $self->type('int', $sortkey),
sortkey => $self->type('int', $sortkey), # deprecated
visibility_values => [$self->type('string', $product_name)],
});
}
......@@ -200,9 +201,10 @@ sub _legal_field_values {
}
push (@result, {
name => $self->type('string', $status->name),
is_open => $self->type('boolean', $status->is_open),
sortkey => $self->type('int', $status->sortkey),
name => $self->type('string', $status->name),
is_open => $self->type('boolean', $status->is_open),
sort_key => $self->type('int', $status->sortkey),
sortkey => $self->type('int', $status->sortkey), # depricated
can_change_to => \@can_change_to,
visibility_values => [],
});
......@@ -214,8 +216,9 @@ sub _legal_field_values {
foreach my $value (@values) {
my $vis_val = $value->visibility_value;
push(@result, {
name => $self->type('string', $value->name),
sortkey => $self->type('int' , $value->sortkey),
name => $self->type('string', $value->name),
sort_key => $self->type('int' , $value->sortkey),
sortkey => $self->type('int' , $value->sortkey), # depricated
visibility_values => [
defined $vis_val ? $self->type('string', $vis_val->name)
: ()
......@@ -1110,11 +1113,15 @@ Each hash has the following keys:
C<string> The actual value--this is what you would specify for this
field in L</create>, etc.
=item C<sortkey>
=item C<sort_key>
C<int> Values, when displayed in a list, are sorted first by this integer
and then secondly by their name.
=item C<sortkey>
B<DEPRECATED> - Use C<sort_key> instead.
=item C<visibility_values>
If C<value_field> is defined for this field, then this value is only shown
......@@ -1171,6 +1178,8 @@ You specified an invalid field name or id.
=item The C<is_mandatory> return value was added in Bugzilla B<4.0>.
=item C<sortkey> was renamed to C<sort_key> in Bugzilla B<4.2>.
=back
=back
......
......@@ -14,6 +14,7 @@
#
# Contributor(s): Marc Schumann <wurblzap@gmail.com>
# Mads Bondo Dydensborg <mbd@dbc.dk>
# Byron Jones <glob@mozilla.com>
package Bugzilla::WebService::Product;
......@@ -24,7 +25,7 @@ use Bugzilla::User;
use Bugzilla::Error;
use Bugzilla::Constants;
use Bugzilla::WebService::Constants;
use Bugzilla::WebService::Util qw(validate);
use Bugzilla::WebService::Util qw(validate filter filter_wants);
use constant READ_ONLY => qw(
get
......@@ -54,31 +55,44 @@ sub get_accessible_products {
return {ids => [map {$_->id} @{Bugzilla->user->get_accessible_products}]};
}
# Get a list of actual products, based on list of ids
# Get a list of actual products, based on list of ids or names
sub get {
my ($self, $params) = validate(@_, 'ids');
my ($self, $params) = validate(@_, 'ids', 'names');
# Only products that are in the users accessible products,
# can be allowed to be returned
my $accessible_products = Bugzilla->user->get_accessible_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;
my @requested_accessible;
if (defined $params->{ids}) {
# 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.
push(@requested_accessible,
grep { $ids{$_->id} } @$accessible_products);
}
if (defined $params->{names}) {
# Create a hash with the names the user wants
my %names = map { lc($_) => 1 } @{$params->{names}};
# Return the intersection of this, by grepping the names from
# accessible products, union'ed with products found by ID to
# avoid duplicates
foreach my $product (grep { $names{lc $_->name} }
@$accessible_products) {
next if grep { $_->id == $product->id }
@requested_accessible;
push @requested_accessible, $product;
}
}
# Now create a result entry for each.
my @products =
map {{
internals => $_,
id => $self->type('int', $_->id),
name => $self->type('string', $_->name),
description => $self->type('string', $_->description),
}
} @requested_accessible;
my @products = map { $self->_product_to_hash($params, $_) }
@requested_accessible;
return { products => \@products };
}
......@@ -104,6 +118,82 @@ sub create {
return { id => $self->type('int', $product->id) };
}
sub _product_to_hash {
my ($self, $params, $product) = @_;
my $field_data = {
internals => $product,
id => $self->type('int', $product->id),
name => $self->type('string', $product->name),
description => $self->type('string', $product->description),
is_active => $self->type('boolean', $product->is_active),
};
if (filter_wants($params, 'components')) {
$field_data->{components} = [map {
$self->_component_to_hash($_)
} @{$product->components}];
}
if (filter_wants($params, 'versions')) {
$field_data->{versions} = [map {
$self->_version_to_hash($_)
} @{$product->versions}];
}
if (filter_wants($params, 'milestones')) {
$field_data->{milestones} = [map {
$self->_milestone_to_hash($_)
} @{$product->milestones}];
}
return filter($params, $field_data);
}
sub _component_to_hash {
my ($self, $component) = @_;
return {
id =>
$self->type('int', $component->id),
name =>
$self->type('string', $component->name),
description =>
$self->type('string' , $component->description),
default_assigned_to =>
$self->type('string' , $component->default_assignee->login),
default_qa_contact =>
$self->type('string' , $component->default_qa_contact->login),
sort_key => # sort_key is returned to match Bug.fields
0,
is_active =>
$self->type('boolean', $component->is_active),
};
}
sub _version_to_hash {
my ($self, $version) = @_;
return {
id =>
$self->type('int', $version->id),
name =>
$self->type('string', $version->name),
sort_key => # sort_key is returened to match Bug.fields
0,
is_active =>
$self->type('boolean', $version->is_active),
};
}
sub _milestone_to_hash {
my ($self, $milestone) = @_;
return {
id =>
$self->type('int', $milestone->id),
name =>
$self->type('string', $milestone->name),
sort_key =>
$self->type('int', $milestone->sortkey),
is_active =>
$self->type('boolean', $milestone->is_active),
};
}
1;
__END__
......@@ -203,17 +293,106 @@ Note: Can also be called as "get_products" for compatibilty with Bugzilla 3.0 AP
=item B<Params>
A hash containing one item, C<ids>, that is an array of product ids.
In addition to the parameters below, this method also accepts the
standard L<include_fields|Bugzilla::WebService/include_fields> and
L<exclude_fields|Bugzilla::WebService/exclude_fields> arguments.
=over
=item C<ids>
An array of product ids
=item C<names>
An array of product names
=back
=item B<Returns>
A hash containing one item, C<products>, that is an array of
hashes. Each hash describes a product, and has the following items:
C<id>, C<name>, C<description>, and C<internals>. The C<id> item is
the id of the product. The C<name> item is the name of the
product. The C<description> is the description of the
product. Finally, the C<internals> is an internal representation of
the product.
=over
=item C<id>
C<int> An integer id uniquely idenfifying the product in this installation only.
=item C<name>
C<string> The name of the product. This is a unique identifier for the
product.
=item C<description>
C<string> A description of the product, which may contain HTML.
=item C<is_active>
C<boolean> A boolean indicating if the product is active.
=item C<components>
C<array> An array of hashes, where each hash describes a component, and has the
following items:
=over
=item C<id>
C<int> An integer id uniquely idenfifying the component in this installation
only.
=item C<name>
C<string> The name of the component. This is a unique identifier for this
component.
=item C<description>
C<string> A description of the component, which may contain HTML.
=item C<default_assigned_to>
C<string> The login name of the user to whom new bugs will be assigned by
default.
=item C<default_qa_contact>
C<string> The login name of the user who will be set as the QA Contact for
new bugs by default.
=item C<sort_key>
C<int> Components, when displayed in a list, are sorted first by this integer
and then secondly by their name.
=item C<is_active>
C<boolean> A boolean indicating if the component is active. Inactive
components are not enabled for new bugs.
=back
=item C<versions>
C<array> An array of hashes, where each hash describes a version, and has the
following items: C<name>, C<sort_key> and C<is_active>.
=item C<milestones>
C<array> An array of hashes, where each hash describes a milestone, and has the
following items: C<name>, C<sort_key> and C<is_active>.
=item C<internals>
B<UNSTABLE>
An internal representation of the product.
=back
Note, that if the user tries to access a product that is not in the
list of accessible products for the user, or a product that does not
......@@ -222,6 +401,17 @@ is returned.
=item B<Errors> (none)
=item B<History>
=over
=item In Bugzilla B<4.2>, C<names> was added as an input parameter.
=item In Bugzilla B<4.2> C<components>, C<versions>, and C<milestones>
were added to the fields returned by C<get>.
=back
=back
=head1 Product Creation
......@@ -262,11 +452,11 @@ C<boolean> Allow the UNCONFIRMED status to be set on bugs in this product.
=item C<classification>
C<boolean> The name of the Classification wich contains this product.
C<string> The name of the Classification which contains this product.
=item C<default_milestone>
C<boolean> The default milestone for this product.
C<string> The default milestone for this product.
=item C<is_open>
......@@ -317,5 +507,3 @@ You must define a default milestone.
=back
=back
=cut
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment