summaryrefslogtreecommitdiffstats
path: root/extensions/MyDashboard/lib/WebService.pm
blob: 78285ca06dc2f5bffbbd088fc015c20090e51d55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
package Bugzilla::Extension::MyDashboard::WebService;

use strict;
use warnings;

use base qw(Bugzilla::WebService);

use Bugzilla::Error;
use Bugzilla::Util qw(detaint_natural trick_taint);

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__

=head1 NAME

Bugzilla::Extension::MyDashboard::Webservice - The MyDashboard WebServices API

=head1 DESCRIPTION

This module contains API methods that are useful to user's of bugzilla.mozilla.org.

=head1 METHODS

See L<Bugzilla::WebService> for a description of how parameters are passed, 
and what B<STABLE>, B<UNSTABLE>, and B<EXPERIMENTAL> mean.