~ubuntu-branches/ubuntu/oneiric/bugzilla/oneiric

« back to all changes in this revision

Viewing changes to Bugzilla/FlagType.pm

  • Committer: Bazaar Package Importer
  • Author(s): Raphael Bossek
  • Date: 2008-06-27 22:34:34 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080627223434-0ib57vstn43bb4a3
Tags: 3.0.4.1-1
* Update of French, Russian and German translations. (closes: #488251)
* Added Bulgarian and Belarusian translations.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- Mode: perl; indent-tabs-mode: nil -*-
2
 
#
3
 
# The contents of this file are subject to the Mozilla Public
4
 
# License Version 1.1 (the "License"); you may not use this file
5
 
# except in compliance with the License. You may obtain a copy of
6
 
# the License at http://www.mozilla.org/MPL/
7
 
#
8
 
# Software distributed under the License is distributed on an "AS
9
 
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10
 
# implied. See the License for the specific language governing
11
 
# rights and limitations under the License.
12
 
#
13
 
# The Original Code is the Bugzilla Bug Tracking System.
14
 
#
15
 
# The Initial Developer of the Original Code is Netscape Communications
16
 
# Corporation. Portions created by Netscape are
17
 
# Copyright (C) 1998 Netscape Communications Corporation. All
18
 
# Rights Reserved.
19
 
#
20
 
# Contributor(s): Myk Melez <myk@mozilla.org>
21
 
#                 Frédéric Buclin <LpSolit@gmail.com>
22
 
 
23
 
use strict;
24
 
 
25
 
package Bugzilla::FlagType;
26
 
 
27
 
=head1 NAME
28
 
 
29
 
Bugzilla::FlagType - A module to deal with Bugzilla flag types.
30
 
 
31
 
=head1 SYNOPSIS
32
 
 
33
 
FlagType.pm provides an interface to flag types as stored in Bugzilla.
34
 
See below for more information.
35
 
 
36
 
=head1 NOTES
37
 
 
38
 
=over
39
 
 
40
 
=item *
41
 
 
42
 
Use of private functions/variables outside this module may lead to
43
 
unexpected results after an upgrade.  Please avoid using private
44
 
functions in other files/modules.  Private functions are functions
45
 
whose names start with _ or are specifically noted as being private.
46
 
 
47
 
=back
48
 
 
49
 
=cut
50
 
 
51
 
use Bugzilla::User;
52
 
use Bugzilla::Error;
53
 
use Bugzilla::Util;
54
 
use Bugzilla::Group;
55
 
 
56
 
use base qw(Bugzilla::Object);
57
 
 
58
 
###############################
59
 
####    Initialization     ####
60
 
###############################
61
 
 
62
 
=begin private
63
 
 
64
 
=head1 PRIVATE VARIABLES/CONSTANTS
65
 
 
66
 
=over
67
 
 
68
 
=item C<DB_COLUMNS>
69
 
 
70
 
basic sets of columns and tables for getting flag types from the
71
 
database.
72
 
 
73
 
=back
74
 
 
75
 
=cut
76
 
 
77
 
use constant DB_COLUMNS => qw(
78
 
    flagtypes.id
79
 
    flagtypes.name
80
 
    flagtypes.description
81
 
    flagtypes.cc_list
82
 
    flagtypes.target_type
83
 
    flagtypes.sortkey
84
 
    flagtypes.is_active
85
 
    flagtypes.is_requestable
86
 
    flagtypes.is_requesteeble
87
 
    flagtypes.is_multiplicable
88
 
    flagtypes.grant_group_id
89
 
    flagtypes.request_group_id
90
 
);
91
 
 
92
 
=pod
93
 
 
94
 
=over
95
 
 
96
 
=item C<DB_TABLE>
97
 
 
98
 
Which database(s) is the data coming from?
99
 
 
100
 
Note: when adding tables to DB_TABLE, make sure to include the separator
101
 
(i.e. words like "LEFT OUTER JOIN") before the table name, since tables take
102
 
multiple separators based on the join type, and therefore it is not possible
103
 
to join them later using a single known separator.
104
 
 
105
 
=back
106
 
 
107
 
=end private
108
 
 
109
 
=cut
110
 
 
111
 
use constant DB_TABLE => 'flagtypes';
112
 
use constant LIST_ORDER => 'flagtypes.sortkey, flagtypes.name';
113
 
 
114
 
###############################
115
 
####      Accessors      ######
116
 
###############################
117
 
 
118
 
=head2 METHODS
119
 
 
120
 
=over
121
 
 
122
 
=item C<id>
123
 
 
124
 
Returns the ID of the flagtype.
125
 
 
126
 
=item C<name>
127
 
 
128
 
Returns the name of the flagtype.
129
 
 
130
 
=item C<description>
131
 
 
132
 
Returns the description of the flagtype.
133
 
 
134
 
=item C<cc_list>
135
 
 
136
 
Returns the concatenated CC list for the flagtype, as a single string.
137
 
 
138
 
=item C<target_type>
139
 
 
140
 
Returns whether the flagtype applies to bugs or attachments.
141
 
 
142
 
=item C<is_active>
143
 
 
144
 
Returns whether the flagtype is active or disabled. Flags being
145
 
in a disabled flagtype are not deleted. It only prevents you from
146
 
adding new flags to it.
147
 
 
148
 
=item C<is_requestable>
149
 
 
150
 
Returns whether you can request for the given flagtype
151
 
(i.e. whether the '?' flag is available or not).
152
 
 
153
 
=item C<is_requesteeble>
154
 
 
155
 
Returns whether you can ask someone specifically or not.
156
 
 
157
 
=item C<is_multiplicable>
158
 
 
159
 
Returns whether you can have more than one flag for the given
160
 
flagtype in a given bug/attachment.
161
 
 
162
 
=item C<sortkey>
163
 
 
164
 
Returns the sortkey of the flagtype.
165
 
 
166
 
=back
167
 
 
168
 
=cut
169
 
 
170
 
sub id               { return $_[0]->{'id'};               }
171
 
sub name             { return $_[0]->{'name'};             }
172
 
sub description      { return $_[0]->{'description'};      }
173
 
sub cc_list          { return $_[0]->{'cc_list'};          }
174
 
sub target_type      { return $_[0]->{'target_type'} eq 'b' ? 'bug' : 'attachment'; }
175
 
sub is_active        { return $_[0]->{'is_active'};        }
176
 
sub is_requestable   { return $_[0]->{'is_requestable'};   }
177
 
sub is_requesteeble  { return $_[0]->{'is_requesteeble'};  }
178
 
sub is_multiplicable { return $_[0]->{'is_multiplicable'}; }
179
 
sub sortkey          { return $_[0]->{'sortkey'};          }
180
 
 
181
 
###############################
182
 
####       Methods         ####
183
 
###############################
184
 
 
185
 
=pod
186
 
 
187
 
=over
188
 
 
189
 
=item C<grant_group>
190
 
 
191
 
Returns the group (as a Bugzilla::Group object) in which a user
192
 
must be in order to grant or deny a request.
193
 
 
194
 
=item C<request_group>
195
 
 
196
 
Returns the group (as a Bugzilla::Group object) in which a user
197
 
must be in order to request or clear a flag.
198
 
 
199
 
=item C<flag_count>
200
 
 
201
 
Returns the number of flags belonging to the flagtype.
202
 
 
203
 
=item C<inclusions>
204
 
 
205
 
Return a hash of product/component IDs and names
206
 
explicitly associated with the flagtype.
207
 
 
208
 
=item C<exclusions>
209
 
 
210
 
Return a hash of product/component IDs and names
211
 
explicitly excluded from the flagtype.
212
 
 
213
 
=back
214
 
 
215
 
=cut
216
 
 
217
 
sub grant_group {
218
 
    my $self = shift;
219
 
 
220
 
    if (!defined $self->{'grant_group'} && $self->{'grant_group_id'}) {
221
 
        $self->{'grant_group'} = new Bugzilla::Group($self->{'grant_group_id'});
222
 
    }
223
 
    return $self->{'grant_group'};
224
 
}
225
 
 
226
 
sub request_group {
227
 
    my $self = shift;
228
 
 
229
 
    if (!defined $self->{'request_group'} && $self->{'request_group_id'}) {
230
 
        $self->{'request_group'} = new Bugzilla::Group($self->{'request_group_id'});
231
 
    }
232
 
    return $self->{'request_group'};
233
 
}
234
 
 
235
 
sub flag_count {
236
 
    my $self = shift;
237
 
 
238
 
    if (!defined $self->{'flag_count'}) {
239
 
        $self->{'flag_count'} =
240
 
            Bugzilla->dbh->selectrow_array('SELECT COUNT(*) FROM flags
241
 
                                            WHERE type_id = ?', undef, $self->{'id'});
242
 
    }
243
 
    return $self->{'flag_count'};
244
 
}
245
 
 
246
 
sub inclusions {
247
 
    my $self = shift;
248
 
 
249
 
    $self->{'inclusions'} ||= get_clusions($self->id, 'in');
250
 
    return $self->{'inclusions'};
251
 
}
252
 
 
253
 
sub exclusions {
254
 
    my $self = shift;
255
 
 
256
 
    $self->{'exclusions'} ||= get_clusions($self->id, 'ex');
257
 
    return $self->{'exclusions'};
258
 
}
259
 
 
260
 
######################################################################
261
 
# Public Functions
262
 
######################################################################
263
 
 
264
 
=pod
265
 
 
266
 
=head1 PUBLIC FUNCTIONS/METHODS
267
 
 
268
 
=over
269
 
 
270
 
=item C<get_clusions($id, $type)>
271
 
 
272
 
Return a hash of product/component IDs and names
273
 
associated with the flagtype:
274
 
$clusions{'product_name:component_name'} = "product_ID:component_ID"
275
 
 
276
 
=back
277
 
 
278
 
=cut
279
 
 
280
 
sub get_clusions {
281
 
    my ($id, $type) = @_;
282
 
    my $dbh = Bugzilla->dbh;
283
 
 
284
 
    my $list =
285
 
        $dbh->selectall_arrayref("SELECT products.id, products.name, " .
286
 
                                 "       components.id, components.name " . 
287
 
                                 "FROM flagtypes, flag${type}clusions " . 
288
 
                                 "LEFT OUTER JOIN products " .
289
 
                                 "  ON flag${type}clusions.product_id = products.id " . 
290
 
                                 "LEFT OUTER JOIN components " .
291
 
                                 "  ON flag${type}clusions.component_id = components.id " . 
292
 
                                 "WHERE flagtypes.id = ? " .
293
 
                                 " AND flag${type}clusions.type_id = flagtypes.id",
294
 
                                 undef, $id);
295
 
    my %clusions;
296
 
    foreach my $data (@$list) {
297
 
        my ($product_id, $product_name, $component_id, $component_name) = @$data;
298
 
        $product_id ||= 0;
299
 
        $product_name ||= "__Any__";
300
 
        $component_id ||= 0;
301
 
        $component_name ||= "__Any__";
302
 
        $clusions{"$product_name:$component_name"} = "$product_id:$component_id";
303
 
    }
304
 
    return \%clusions;
305
 
}
306
 
 
307
 
=pod
308
 
 
309
 
=over
310
 
 
311
 
=item C<match($criteria)>
312
 
 
313
 
Queries the database for flag types matching the given criteria
314
 
and returns a list of matching flagtype objects.
315
 
 
316
 
=back
317
 
 
318
 
=cut
319
 
 
320
 
sub match {
321
 
    my ($criteria) = @_;
322
 
    my $dbh = Bugzilla->dbh;
323
 
 
324
 
    # Depending on the criteria, we may have to append additional tables.
325
 
    my $tables = [DB_TABLE];
326
 
    my @criteria = sqlify_criteria($criteria, $tables);
327
 
    $tables = join(' ', @$tables);
328
 
    $criteria = join(' AND ', @criteria);
329
 
 
330
 
    my $flagtype_ids = $dbh->selectcol_arrayref("SELECT id FROM $tables WHERE $criteria");
331
 
 
332
 
    return Bugzilla::FlagType->new_from_list($flagtype_ids);
333
 
}
334
 
 
335
 
=pod
336
 
 
337
 
=over
338
 
 
339
 
=item C<count($criteria)>
340
 
 
341
 
Returns the total number of flag types matching the given criteria.
342
 
 
343
 
=back
344
 
 
345
 
=cut
346
 
 
347
 
sub count {
348
 
    my ($criteria) = @_;
349
 
    my $dbh = Bugzilla->dbh;
350
 
 
351
 
    # Depending on the criteria, we may have to append additional tables.
352
 
    my $tables = [DB_TABLE];
353
 
    my @criteria = sqlify_criteria($criteria, $tables);
354
 
    $tables = join(' ', @$tables);
355
 
    $criteria = join(' AND ', @criteria);
356
 
 
357
 
    my $count = $dbh->selectrow_array("SELECT COUNT(flagtypes.id)
358
 
                                       FROM $tables WHERE $criteria");
359
 
    return $count;
360
 
}
361
 
 
362
 
######################################################################
363
 
# Private Functions
364
 
######################################################################
365
 
 
366
 
=begin private
367
 
 
368
 
=head1 PRIVATE FUNCTIONS
369
 
 
370
 
=over
371
 
 
372
 
=item C<sqlify_criteria($criteria, $tables)>
373
 
 
374
 
Converts a hash of criteria into a list of SQL criteria.
375
 
$criteria is a reference to the criteria (field => value), 
376
 
$tables is a reference to an array of tables being accessed 
377
 
by the query.
378
 
 
379
 
=back
380
 
 
381
 
=cut
382
 
 
383
 
sub sqlify_criteria {
384
 
    my ($criteria, $tables) = @_;
385
 
    my $dbh = Bugzilla->dbh;
386
 
 
387
 
    # the generated list of SQL criteria; "1=1" is a clever way of making sure
388
 
    # there's something in the list so calling code doesn't have to check list
389
 
    # size before building a WHERE clause out of it
390
 
    my @criteria = ("1=1");
391
 
 
392
 
    if ($criteria->{name}) {
393
 
        my $name = $dbh->quote($criteria->{name});
394
 
        trick_taint($name); # Detaint data as we have quoted it.
395
 
        push(@criteria, "flagtypes.name = $name");
396
 
    }
397
 
    if ($criteria->{target_type}) {
398
 
        # The target type is stored in the database as a one-character string
399
 
        # ("a" for attachment and "b" for bug), but this function takes complete
400
 
        # names ("attachment" and "bug") for clarity, so we must convert them.
401
 
        my $target_type = $criteria->{target_type} eq 'bug'? 'b' : 'a';
402
 
        push(@criteria, "flagtypes.target_type = '$target_type'");
403
 
    }
404
 
    if (exists($criteria->{is_active})) {
405
 
        my $is_active = $criteria->{is_active} ? "1" : "0";
406
 
        push(@criteria, "flagtypes.is_active = $is_active");
407
 
    }
408
 
    if ($criteria->{product_id} && $criteria->{'component_id'}) {
409
 
        my $product_id = $criteria->{product_id};
410
 
        my $component_id = $criteria->{component_id};
411
 
        
412
 
        # Add inclusions to the query, which simply involves joining the table
413
 
        # by flag type ID and target product/component.
414
 
        push(@$tables, "INNER JOIN flaginclusions AS i ON flagtypes.id = i.type_id");
415
 
        push(@criteria, "(i.product_id = $product_id OR i.product_id IS NULL)");
416
 
        push(@criteria, "(i.component_id = $component_id OR i.component_id IS NULL)");
417
 
        
418
 
        # Add exclusions to the query, which is more complicated.  First of all,
419
 
        # we do a LEFT JOIN so we don't miss flag types with no exclusions.
420
 
        # Then, as with inclusions, we join on flag type ID and target product/
421
 
        # component.  However, since we want flag types that *aren't* on the
422
 
        # exclusions list, we add a WHERE criteria to use only records with
423
 
        # NULL exclusion type, i.e. without any exclusions.
424
 
        my $join_clause = "flagtypes.id = e.type_id " .
425
 
                          "AND (e.product_id = $product_id OR e.product_id IS NULL) " .
426
 
                          "AND (e.component_id = $component_id OR e.component_id IS NULL)";
427
 
        push(@$tables, "LEFT JOIN flagexclusions AS e ON ($join_clause)");
428
 
        push(@criteria, "e.type_id IS NULL");
429
 
    }
430
 
    if ($criteria->{group}) {
431
 
        my $gid = $criteria->{group};
432
 
        detaint_natural($gid);
433
 
        push(@criteria, "(flagtypes.grant_group_id = $gid " .
434
 
                        " OR flagtypes.request_group_id = $gid)");
435
 
    }
436
 
    
437
 
    return @criteria;
438
 
}
439
 
 
440
 
1;
441
 
 
442
 
=end private
443
 
 
444
 
=head1 SEE ALSO
445
 
 
446
 
=over
447
 
 
448
 
=item B<Bugzilla::Flags>
449
 
 
450
 
=back
451
 
 
452
 
=head1 CONTRIBUTORS
453
 
 
454
 
=over
455
 
 
456
 
=item Myk Melez <myk@mozilla.org>
457
 
 
458
 
=item Kevin Benton <kevin.benton@amd.com>
459
 
 
460
 
=item Frédéric Buclin <LpSolit@gmail.com>
461
 
 
462
 
=back
463
 
 
464
 
=cut