summaryrefslogtreecommitdiffstats
path: root/extensions/ProdCompSearch/lib/WebService.pm
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/ProdCompSearch/lib/WebService.pm')
-rw-r--r--extensions/ProdCompSearch/lib/WebService.pm237
1 files changed, 126 insertions, 111 deletions
diff --git a/extensions/ProdCompSearch/lib/WebService.pm b/extensions/ProdCompSearch/lib/WebService.pm
index b173137dd..b47b4a402 100644
--- a/extensions/ProdCompSearch/lib/WebService.pm
+++ b/extensions/ProdCompSearch/lib/WebService.pm
@@ -21,20 +21,21 @@ use Bugzilla::Util qw(detaint_natural trick_taint trim);
#############
use constant PUBLIC_METHODS => qw(
- prod_comp_search
+ prod_comp_search
);
sub rest_resources {
- return [
- qr{^/prod_comp_search/(.*)$}, {
- GET => {
- method => 'prod_comp_search',
- params => sub {
- return { search => $_[0] }
- }
- }
+ return [
+ qr{^/prod_comp_search/(.*)$},
+ {
+ GET => {
+ method => 'prod_comp_search',
+ params => sub {
+ return {search => $_[0]};
}
- ]
+ }
+ }
+ ];
}
##################
@@ -42,79 +43,91 @@ sub rest_resources {
##################
sub prod_comp_search {
- my ($self, $params) = @_;
- my $user = Bugzilla->user;
- my $dbh = Bugzilla->switch_to_shadow_db();
-
- my $search = trim($params->{'search'} || '');
- $search || ThrowCodeError('param_required',
- { function => 'PCS.prod_comp_search', param => 'search' });
-
- my $limit = detaint_natural($params->{'limit'})
- ? $dbh->sql_limit($params->{'limit'})
- : '';
-
- # We do this in the DB directly as we want it to be fast and
- # not have the overhead of loading full product objects
-
- # All products which the user has "Entry" access to.
- my $enterable_ids = $dbh->selectcol_arrayref(
- 'SELECT products.id FROM products
+ my ($self, $params) = @_;
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->switch_to_shadow_db();
+
+ my $search = trim($params->{'search'} || '');
+ $search
+ || ThrowCodeError('param_required',
+ {function => 'PCS.prod_comp_search', param => 'search'});
+
+ my $limit
+ = detaint_natural($params->{'limit'})
+ ? $dbh->sql_limit($params->{'limit'})
+ : '';
+
+ # We do this in the DB directly as we want it to be fast and
+ # not have the overhead of loading full product objects
+
+ # All products which the user has "Entry" access to.
+ my $enterable_ids = $dbh->selectcol_arrayref(
+ 'SELECT products.id FROM products
LEFT JOIN group_control_map
ON group_control_map.product_id = products.id
AND group_control_map.entry != 0
AND group_id NOT IN (' . $user->groups_as_string . ')
WHERE group_id IS NULL
- AND products.isactive = 1');
-
- if (scalar @$enterable_ids) {
- # And all of these products must have at least one component
- # and one version.
- $enterable_ids = $dbh->selectcol_arrayref(
- 'SELECT DISTINCT products.id FROM products
- WHERE ' . $dbh->sql_in('products.id', $enterable_ids) .
- ' AND products.id IN (SELECT DISTINCT components.product_id
+ AND products.isactive = 1'
+ );
+
+ if (scalar @$enterable_ids) {
+
+ # And all of these products must have at least one component
+ # and one version.
+ $enterable_ids = $dbh->selectcol_arrayref(
+ 'SELECT DISTINCT products.id FROM products
+ WHERE '
+ . $dbh->sql_in('products.id', $enterable_ids)
+ . ' AND products.id IN (SELECT DISTINCT components.product_id
FROM components
WHERE components.isactive = 1)
AND products.id IN (SELECT DISTINCT versions.product_id
FROM versions
- WHERE versions.isactive = 1)');
- }
-
- return { products => [] } if !scalar @$enterable_ids;
-
- trick_taint($search);
- my @terms;
- my @order;
-
- if ($search =~ /^(.*?)::(.*)$/) {
- my ($product, $component) = (trim($1), trim($2));
- push @terms, _build_terms($product, 1, 0);
- push @terms, _build_terms($component, 0, 1);
- push @order, "products.name != " . $dbh->quote($product) if $product ne '';
- push @order, "components.name != " . $dbh->quote($component) if $component ne '';
- push @order, _build_like_order($product . ' ' . $component);
- push @order, "products.name";
- push @order, "components.name";
- } else {
- push @terms, _build_terms($search, 1, 1);
- push @order, "products.name != " . $dbh->quote($search);
- push @order, "components.name != " . $dbh->quote($search);
- push @order, _build_like_order($search);
- push @order, "products.name";
- push @order, "components.name";
- }
- return { products => [] } if !scalar @terms;
-
- # To help mozilla staff file bmo administration bugs into the right
- # component, sort bmo first when searching for 'bugzilla'
- if ($search =~ /bugzilla/i && $search !~ /^bugzilla\s*::/i
- && ($user->in_group('mozilla-corporation') || $user->in_group('mozilla-foundation')))
- {
- unshift @order, "products.name != 'bugzilla.mozilla.org'";
- }
-
- my $components = $dbh->selectall_arrayref("
+ WHERE versions.isactive = 1)'
+ );
+ }
+
+ return {products => []} if !scalar @$enterable_ids;
+
+ trick_taint($search);
+ my @terms;
+ my @order;
+
+ if ($search =~ /^(.*?)::(.*)$/) {
+ my ($product, $component) = (trim($1), trim($2));
+ push @terms, _build_terms($product, 1, 0);
+ push @terms, _build_terms($component, 0, 1);
+ push @order, "products.name != " . $dbh->quote($product) if $product ne '';
+ push @order, "components.name != " . $dbh->quote($component)
+ if $component ne '';
+ push @order, _build_like_order($product . ' ' . $component);
+ push @order, "products.name";
+ push @order, "components.name";
+ }
+ else {
+ push @terms, _build_terms($search, 1, 1);
+ push @order, "products.name != " . $dbh->quote($search);
+ push @order, "components.name != " . $dbh->quote($search);
+ push @order, _build_like_order($search);
+ push @order, "products.name";
+ push @order, "components.name";
+ }
+ return {products => []} if !scalar @terms;
+
+ # To help mozilla staff file bmo administration bugs into the right
+ # component, sort bmo first when searching for 'bugzilla'
+ if (
+ $search =~ /bugzilla/i
+ && $search !~ /^bugzilla\s*::/i
+ && ( $user->in_group('mozilla-corporation')
+ || $user->in_group('mozilla-foundation'))
+ )
+ {
+ unshift @order, "products.name != 'bugzilla.mozilla.org'";
+ }
+
+ my $components = $dbh->selectall_arrayref("
SELECT products.name AS product,
components.name AS component
FROM products
@@ -122,19 +135,18 @@ sub prod_comp_search {
WHERE (" . join(" AND ", @terms) . ")
AND products.id IN (" . join(",", @$enterable_ids) . ")
AND components.isactive = 1
- ORDER BY " . join(", ", @order) . " $limit",
- { Slice => {} });
-
- my $products = [];
- my $current_product;
- foreach my $component (@$components) {
- if (!$current_product || $component->{product} ne $current_product) {
- $current_product = $component->{product};
- push @$products, { product => $current_product };
- }
- push @$products, $component;
+ ORDER BY " . join(", ", @order) . " $limit", {Slice => {}});
+
+ my $products = [];
+ my $current_product;
+ foreach my $component (@$components) {
+ if (!$current_product || $component->{product} ne $current_product) {
+ $current_product = $component->{product};
+ push @$products, {product => $current_product};
}
- return { products => $products };
+ push @$products, $component;
+ }
+ return {products => $products};
}
###################
@@ -142,34 +154,37 @@ sub prod_comp_search {
###################
sub _build_terms {
- my ($query, $product, $component) = @_;
- my $dbh = Bugzilla->dbh();
-
- my @fields;
- push @fields, 'products.name', 'products.description' if $product;
- push @fields, 'components.name', 'components.description' if $component;
- # note: CONCAT_WS is MySQL specific
- my $field = "CONCAT_WS(' ', ". join(',', @fields) . ")";
-
- my @terms;
- foreach my $word (split(/[\s,]+/, $query)) {
- push(@terms, $dbh->sql_iposition($dbh->quote($word), $field) . " > 0")
- if $word ne '';
- }
- return @terms;
+ my ($query, $product, $component) = @_;
+ my $dbh = Bugzilla->dbh();
+
+ my @fields;
+ push @fields, 'products.name', 'products.description' if $product;
+ push @fields, 'components.name', 'components.description' if $component;
+
+ # note: CONCAT_WS is MySQL specific
+ my $field = "CONCAT_WS(' ', " . join(',', @fields) . ")";
+
+ my @terms;
+ foreach my $word (split(/[\s,]+/, $query)) {
+ push(@terms, $dbh->sql_iposition($dbh->quote($word), $field) . " > 0")
+ if $word ne '';
+ }
+ return @terms;
}
sub _build_like_order {
- my ($query) = @_;
- my $dbh = Bugzilla->dbh;
-
- my @terms;
- foreach my $word (split(/[\s,]+/, $query)) {
- push @terms, "CONCAT(products.name, components.name) LIKE " . $dbh->quote('%' . $word . '%')
- if $word ne '';
- }
-
- return 'NOT(' . join(' AND ', @terms) . ')';
+ my ($query) = @_;
+ my $dbh = Bugzilla->dbh;
+
+ my @terms;
+ foreach my $word (split(/[\s,]+/, $query)) {
+ push @terms,
+ "CONCAT(products.name, components.name) LIKE "
+ . $dbh->quote('%' . $word . '%')
+ if $word ne '';
+ }
+
+ return 'NOT(' . join(' AND ', @terms) . ')';
}
1;