Commit b799069b authored by Dave Lawrence's avatar Dave Lawrence

Bug 896066 - Allow REST WebService API to for GET /product to allow retrieval of…

Bug 896066 - Allow REST WebService API to for GET /product to allow retrieval of multiple product objects r/a=glob
parent 927f0c3a
......@@ -67,47 +67,76 @@ sub get_accessible_products {
# Get a list of actual products, based on list of ids or names
sub get {
my ($self, $params) = validate(@_, 'ids', 'names');
my ($self, $params) = validate(@_, 'ids', 'names', 'type');
my $user = Bugzilla->user;
defined $params->{ids} || defined $params->{names}
defined $params->{ids} || defined $params->{names} || defined $params->{type}
|| ThrowCodeError("params_required", { function => "Product.get",
params => ['ids', 'names'] });
params => ['ids', 'names', 'type'] });
Bugzilla->switch_to_shadow_db();
# Only products that are in the users accessible products,
# can be allowed to be returned
my $accessible_products = Bugzilla->user->get_accessible_products;
my $products = [];
if (defined $params->{type}) {
my %product_hash;
my $found = 0;
foreach my $type (@{ $params->{type} }) {
my $result = [];
if ($type eq 'accessible') {
$result = $user->get_accessible_products();
}
elsif ($type eq 'enterable') {
$result = $user->get_enterable_products();
}
elsif ($type eq 'selectable') {
$result = $user->get_selectable_products();
}
else {
ThrowUserError('get_products_invalid_type',
{ type => $type });
}
map { $product_hash{$_->id} = $_ } @$result;
}
$products = [ values %product_hash ];
}
else {
$products = $user->get_accessible_products;
}
my @requested_accessible;
my @requested_products;
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);
# Return the intersection of this, by grepping the ids from $products.
push(@requested_products,
grep { $ids{$_->id} } @$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
# Return the intersection of this, by grepping the names
# from $products, union'ed with products found by ID to
# avoid duplicates
foreach my $product (grep { $names{lc $_->name} }
@$accessible_products) {
@$products) {
next if grep { $_->id == $product->id }
@requested_accessible;
push @requested_accessible, $product;
@requested_products;
push @requested_products, $product;
}
}
# If we just requested a specific type of products without
# specifying ids or names, then return the entire list.
if (!defined $params->{ids} && !defined $params->{names}) {
@requested_products = @$products;
}
# Now create a result entry for each.
my @products = map { $self->_product_to_hash($params, $_) }
@requested_accessible;
@requested_products;
return { products => \@products };
}
......@@ -354,7 +383,7 @@ Returns a list of the ids of the products the user can search on.
=item B<REST>
GET /product?type=selectable
GET /product_selectable
the returned data format is same as below.
......@@ -390,7 +419,7 @@ against.
=item B<REST>
GET /product?type=enterable
GET /product_enterable
the returned data format is same as below.
......@@ -426,7 +455,7 @@ bugs against.
=item B<REST>
GET /product?type=accessible
GET /product_accessible
the returned data format is same as below.
......@@ -465,8 +494,20 @@ B<Note>: Can also be called as "get_products" for compatibilty with Bugzilla 3.0
=item B<REST>
To return information about a specific groups of products such as
C<accessible>, C<selectable>, or C<enterable>:
GET /product?type=accessible
To return information about a specific product by C<id> or C<name>:
GET /product/<product_id_or_name>
You can also return information about more than one specific product
by using the following in your query string:
GET /product?ids=1&ids=2&ids=3 or GET /product?names=ProductOne&names=Product2
the returned data format is same as below.
=item B<Params>
......@@ -487,6 +528,12 @@ An array of product ids
An array of product names
=item C<type>
The group of products to return. Valid values are: C<accessible> (default),
C<selectable>, and C<enterable>. C<type> can be a single value or an array
of values if more than one group is needed with duplicates removed.
=back
=item B<Returns>
......
......@@ -21,17 +21,24 @@ BEGIN {
sub _rest_resources {
my $rest_resources = [
qr{^/product$}, {
qr{^/product_accessible$}, {
GET => {
method => 'get_accessible_products'
}
},
qr{^/product_enterable$}, {
GET => {
method => 'get_enterable_products'
}
},
qr{^/product_selectable$}, {
GET => {
method => sub {
my $type = Bugzilla->input_params->{type};
return 'get_accessible_products'
if !defined $type || $type eq 'accessible';
return 'get_enterable_products' if $type eq 'enterable';
return 'get_selectable_products' if $type eq 'selectable';
ThrowUserError('rest_get_products_invalid_type',
{ type => $type });
method => 'get_selectable_products'
}
},
qr{^/product$}, {
GET => {
method => 'get'
},
POST => {
method => 'create',
......
......@@ -1081,9 +1081,9 @@
[% ELSIF error == "rest_invalid_resource" %]
A REST API resource was not found for '[% method FILTER html +%] [%+ path FILTER html %]'.
[% ELSIF error == "rest_get_products_invalid_type" %]
The type '[% type FILTER html %]' is invalid for 'GET /product'. Valid choices
are 'accessible' (default if type value is undefined), 'selectable', and 'enterable'.
[% ELSIF error == "get_products_invalid_type" %]
The product type '[% type FILTER html %]' is invalid. Valid choices
are 'accessible', 'selectable', and 'enterable'.
[% ELSIF error == "keyword_already_exists" %]
[% title = "Keyword Already Exists" %]
......
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