summaryrefslogtreecommitdiffstats
path: root/extensions/BMO/lib/WebService.pm
diff options
context:
space:
mode:
authorDave Lawrence <dlawrence@mozilla.com>2012-05-24 18:57:14 +0200
committerDave Lawrence <dlawrence@mozilla.com>2012-05-24 18:57:14 +0200
commit95052864ee662a67639a3080b3ecf7a1e24ba9e3 (patch)
treec1e771d9b53c622e44c27162fa5c40b5bfb5fa15 /extensions/BMO/lib/WebService.pm
parentd1fdd23fc3155f8e78d724713efccaae3d9ab5b9 (diff)
downloadbugzilla-95052864ee662a67639a3080b3ecf7a1e24ba9e3.tar.gz
bugzilla-95052864ee662a67639a3080b3ecf7a1e24ba9e3.tar.xz
Bug 747193 - Add search field to product chooser to allow selecting product/component based on keyword search
r=glob
Diffstat (limited to 'extensions/BMO/lib/WebService.pm')
-rw-r--r--extensions/BMO/lib/WebService.pm67
1 files changed, 67 insertions, 0 deletions
diff --git a/extensions/BMO/lib/WebService.pm b/extensions/BMO/lib/WebService.pm
index 95bdcbdf3..cd3b9a92c 100644
--- a/extensions/BMO/lib/WebService.pm
+++ b/extensions/BMO/lib/WebService.pm
@@ -26,6 +26,7 @@ use base qw(Bugzilla::WebService);
use Bugzilla::Constants;
use Bugzilla::Error;
+use Bugzilla::Util qw(detaint_natural trick_taint);
use Bugzilla::WebService::Util qw(validate);
use Bugzilla::Field;
@@ -99,6 +100,72 @@ sub getBugsVerifier {
return \%users;
}
+sub prod_comp_search {
+ my ($self, $params) = @_;
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->switch_to_shadow_db();
+
+ my $search = $params->{'search'};
+ $search || ThrowCodeError('param_required',
+ { function => 'Bug.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
+ 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;
+
+ my @list;
+ foreach my $word (split(/[\s,]+/, $search)) {
+ if ($word ne "") {
+ my $sql_word = $dbh->quote($word);
+ trick_taint($sql_word);
+ # XXX CONCAT_WS is MySQL specific
+ my $field = "CONCAT_WS(' ', products.name, components.name, components.description)";
+ push(@list, $dbh->sql_iposition($sql_word, $field) . " > 0");
+ }
+ }
+
+ my $products = $dbh->selectall_arrayref("
+ SELECT products.name AS product,
+ components.name AS component
+ FROM products
+ INNER JOIN components ON products.id = components.product_id
+ WHERE (" . join(" AND ", @list) . ")
+ AND products.id IN (" . join(",", @$enterable_ids) . ")
+ ORDER BY products.name $limit",
+ { Slice => {} });
+
+ return { products => $products };
+}
+
1;
__END__