зеркало из https://github.com/mozilla/gecko-dev.git
Bug 339380: Make Bugzilla::Component use Bugzilla::Object
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=LpSolit, a=myk
This commit is contained in:
Родитель
5b3710b4fd
Коммит
7cabcbf258
|
@ -21,6 +21,8 @@ use strict;
|
|||
|
||||
package Bugzilla::Component;
|
||||
|
||||
use base qw(Bugzilla::Object);
|
||||
|
||||
use Bugzilla::Util;
|
||||
use Bugzilla::Error;
|
||||
use Bugzilla::User;
|
||||
|
@ -30,68 +32,50 @@ use Bugzilla::FlagType;
|
|||
#### Initialization ####
|
||||
###############################
|
||||
|
||||
use constant DB_COLUMNS => qw(
|
||||
components.id
|
||||
components.name
|
||||
components.product_id
|
||||
components.initialowner
|
||||
components.initialqacontact
|
||||
components.description
|
||||
);
|
||||
use constant DB_TABLE => 'components';
|
||||
|
||||
our $columns = join(", ", DB_COLUMNS);
|
||||
use constant DB_COLUMNS => qw(
|
||||
id
|
||||
name
|
||||
product_id
|
||||
initialowner
|
||||
initialqacontact
|
||||
description
|
||||
);
|
||||
|
||||
###############################
|
||||
#### Methods ####
|
||||
###############################
|
||||
|
||||
sub new {
|
||||
my $invocant = shift;
|
||||
my $class = ref($invocant) || $invocant;
|
||||
my $self = {};
|
||||
bless($self, $class);
|
||||
return $self->_init(@_);
|
||||
}
|
||||
|
||||
sub _init {
|
||||
my $self = shift;
|
||||
my ($param) = (@_);
|
||||
my $class = shift;
|
||||
my $param = shift;
|
||||
my $dbh = Bugzilla->dbh;
|
||||
|
||||
my $id = $param unless (ref $param eq 'HASH');
|
||||
my $component;
|
||||
my $product;
|
||||
if (ref $param) {
|
||||
$product = $param->{product};
|
||||
my $name = $param->{name};
|
||||
if (!defined $product) {
|
||||
ThrowCodeError('bad_arg',
|
||||
{argument => 'product',
|
||||
function => "${class}::new"});
|
||||
}
|
||||
if (!defined $name) {
|
||||
ThrowCodeError('bad_arg',
|
||||
{argument => 'name',
|
||||
function => "${class}::new"});
|
||||
}
|
||||
|
||||
if (defined $id) {
|
||||
detaint_natural($id)
|
||||
|| ThrowCodeError('param_must_be_numeric',
|
||||
{function => 'Bugzilla::Component::_init'});
|
||||
|
||||
$component = $dbh->selectrow_hashref(qq{
|
||||
SELECT $columns FROM components
|
||||
WHERE id = ?}, undef, $id);
|
||||
|
||||
} elsif (defined $param->{'product_id'}
|
||||
&& detaint_natural($param->{'product_id'})
|
||||
&& defined $param->{'name'}) {
|
||||
|
||||
trick_taint($param->{'name'});
|
||||
|
||||
$component = $dbh->selectrow_hashref(qq{
|
||||
SELECT $columns FROM components
|
||||
WHERE name = ? AND product_id = ?}, undef,
|
||||
($param->{'name'}, $param->{'product_id'}));
|
||||
} else {
|
||||
ThrowCodeError('bad_arg',
|
||||
{argument => 'param',
|
||||
function => 'Bugzilla::Component::_init'});
|
||||
my $condition = 'product_id = ? AND name = ?';
|
||||
my @values = ($product->id, $name);
|
||||
$param = { condition => $condition, values => \@values };
|
||||
}
|
||||
|
||||
return undef unless (defined $component);
|
||||
|
||||
foreach my $field (keys %$component) {
|
||||
$self->{$field} = $component->{$field};
|
||||
}
|
||||
return $self;
|
||||
unshift @_, $param;
|
||||
my $component = $class->SUPER::new(@_);
|
||||
$component->{product} = $product if $product;
|
||||
return $component;
|
||||
}
|
||||
|
||||
sub bug_count {
|
||||
|
@ -204,8 +188,8 @@ sub check_component {
|
|||
}
|
||||
|
||||
my $component =
|
||||
new Bugzilla::Component({product_id => $product->id,
|
||||
name => $comp_name});
|
||||
new Bugzilla::Component({product => $product,
|
||||
name => $comp_name});
|
||||
unless ($component) {
|
||||
ThrowUserError('component_not_valid',
|
||||
{'product' => $product->name,
|
||||
|
@ -227,8 +211,8 @@ Bugzilla::Component - Bugzilla product component class.
|
|||
use Bugzilla::Component;
|
||||
|
||||
my $component = new Bugzilla::Component(1);
|
||||
my $component = new Bugzilla::Component({product_id => 1,
|
||||
name => 'AcmeComp'});
|
||||
my $component = new Bugzilla::Component({product => $product,
|
||||
name => 'AcmeComp'});
|
||||
|
||||
my $bug_count = $component->bug_count();
|
||||
my $bug_ids = $component->bug_ids();
|
||||
|
|
|
@ -60,6 +60,8 @@ sub _init {
|
|||
my $object;
|
||||
|
||||
if (defined $id) {
|
||||
# We special-case if somebody specifies an ID, so that we can
|
||||
# validate it as numeric.
|
||||
detaint_natural($id)
|
||||
|| ThrowCodeError('param_must_be_numeric',
|
||||
{function => $class . '::_init'});
|
||||
|
@ -67,23 +69,40 @@ sub _init {
|
|||
$object = $dbh->selectrow_hashref(qq{
|
||||
SELECT $columns FROM $table
|
||||
WHERE $id_field = ?}, undef, $id);
|
||||
} elsif (defined $param->{'name'}) {
|
||||
trick_taint($param->{'name'});
|
||||
$object = $dbh->selectrow_hashref(qq{
|
||||
SELECT $columns FROM $table
|
||||
WHERE } . $dbh->sql_istrcmp($name_field, '?'),
|
||||
undef, $param->{'name'});
|
||||
} else {
|
||||
ThrowCodeError('bad_arg',
|
||||
{argument => 'param',
|
||||
function => $class . '::_init'});
|
||||
unless (defined $param->{name} || (defined $param->{'condition'}
|
||||
&& defined $param->{'values'}))
|
||||
{
|
||||
ThrowCodeError('bad_arg', { argument => 'param',
|
||||
function => $class . '::new' });
|
||||
}
|
||||
|
||||
my ($condition, @values);
|
||||
if (defined $param->{name}) {
|
||||
$condition = $dbh->sql_istrcmp($name_field, '?');
|
||||
push(@values, $param->{name});
|
||||
}
|
||||
elsif (defined $param->{'condition'} && defined $param->{'values'}) {
|
||||
caller->isa('Bugzilla::Object')
|
||||
|| ThrowCodeError('protection_violation',
|
||||
{ caller => caller,
|
||||
function => $class . '::new',
|
||||
argument => 'condition/values' });
|
||||
$condition = $param->{'condition'};
|
||||
push(@values, @{$param->{'values'}});
|
||||
}
|
||||
|
||||
map { trick_taint($_) } @values;
|
||||
$object = $dbh->selectrow_hashref(
|
||||
"SELECT $columns FROM $table WHERE $condition", undef, @values);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
sub new_from_list {
|
||||
my $class = shift;
|
||||
my $invocant = shift;
|
||||
my $class = ref($invocant) || $invocant;
|
||||
my ($id_list) = @_;
|
||||
my $dbh = Bugzilla->dbh;
|
||||
my $columns = join(',', $class->DB_COLUMNS);
|
||||
|
@ -363,17 +382,47 @@ the L</ID_FIELD> usually can't be updated.)
|
|||
|
||||
=item C<new($param)>
|
||||
|
||||
Description: The constructor is used to load an existing object
|
||||
from the database, by id or by name.
|
||||
=over
|
||||
|
||||
Params: $param - If you pass an integer, the integer is the
|
||||
id of the object, from the database, that we
|
||||
want to read in. If you pass in a hash with
|
||||
C<name> key, then the value of the name key
|
||||
is the case-insensitive name of the object from
|
||||
the DB.
|
||||
=item B<Description>
|
||||
|
||||
Returns: A fully-initialized object.
|
||||
The constructor is used to load an existing object from the database,
|
||||
by id or by name.
|
||||
|
||||
=item B<Params>
|
||||
|
||||
If you pass an integer, the integer is the id of the object,
|
||||
from the database, that we want to read in. (id is defined
|
||||
as the value in the L</ID_FIELD> column).
|
||||
|
||||
If you pass in a hash, you can pass a C<name> key. The
|
||||
value of the C<name> key is the case-insensitive name of the object
|
||||
(from L</NAME_FIELD>) in the DB.
|
||||
|
||||
B<Additional Parameters Available for Subclasses>
|
||||
|
||||
If you are a subclass of C<Bugzilla::Object>, you can pass
|
||||
C<condition> and C<values> as hash keys, instead of the above.
|
||||
|
||||
C<condition> is a set of SQL conditions for the WHERE clause, which contain
|
||||
placeholders.
|
||||
|
||||
C<values> is a reference to an array. The array contains the values
|
||||
for each placeholder in C<condition>, in order.
|
||||
|
||||
This is to allow subclasses to have complex parameters, and then to
|
||||
translate those parameters into C<condition> and C<values> when they
|
||||
call C<$self->SUPER::new> (which is this function, usually).
|
||||
|
||||
If you try to call C<new> outside of a subclass with the C<condition>
|
||||
and C<values> parameters, Bugzilla will throw an error. These parameters
|
||||
are intended B<only> for use by subclasses.
|
||||
|
||||
=item B<Returns>
|
||||
|
||||
A fully-initialized object.
|
||||
|
||||
=back
|
||||
|
||||
=item C<new_from_list(\@id_list)>
|
||||
|
||||
|
|
|
@ -65,12 +65,8 @@ sub components {
|
|||
WHERE product_id = ?
|
||||
ORDER BY name}, undef, $self->id);
|
||||
|
||||
my @components;
|
||||
require Bugzilla::Component;
|
||||
foreach my $id (@$ids) {
|
||||
push @components, new Bugzilla::Component($id);
|
||||
}
|
||||
$self->{components} = \@components;
|
||||
$self->{components} = Bugzilla::Component->new_from_list($ids);
|
||||
}
|
||||
return $self->{components};
|
||||
}
|
||||
|
|
|
@ -931,10 +931,7 @@ sub product_responsibilities {
|
|||
|
||||
# We cannot |use| it, because Component.pm already |use|s User.pm.
|
||||
require Bugzilla::Component;
|
||||
my @components;
|
||||
push(@components, new Bugzilla::Component($_)) foreach (@$comp_ids);
|
||||
|
||||
$self->{'product_resp'} = \@components;
|
||||
$self->{'product_resp'} = Bugzilla::Component->new_from_list($comp_ids);
|
||||
return $self->{'product_resp'};
|
||||
}
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ if ($action eq 'new') {
|
|||
}
|
||||
|
||||
my $component =
|
||||
new Bugzilla::Component({product_id => $product->id,
|
||||
new Bugzilla::Component({product => $product,
|
||||
name => $comp_name});
|
||||
|
||||
if ($component) {
|
||||
|
@ -200,7 +200,7 @@ if ($action eq 'new') {
|
|||
($product->id, $comp_name, $description,
|
||||
$default_assignee_id, $default_qa_contact_id));
|
||||
|
||||
$component = new Bugzilla::Component({ product_id => $product->id,
|
||||
$component = new Bugzilla::Component({ product => $product,
|
||||
name => $comp_name });
|
||||
|
||||
my $sth = $dbh->prepare("INSERT INTO component_cc
|
||||
|
@ -383,7 +383,7 @@ if ($action eq 'update') {
|
|||
|
||||
if ($comp_name ne $component_old->name) {
|
||||
my $component =
|
||||
new Bugzilla::Component({product_id => $product->id,
|
||||
new Bugzilla::Component({product => $product,
|
||||
name => $comp_name});
|
||||
if ($component) {
|
||||
ThrowUserError('component_already_exists',
|
||||
|
|
|
@ -326,8 +326,8 @@ sub init() {
|
|||
moved-default-product. \n", "REOPEN", $exporter);
|
||||
my $def_component = new Bugzilla::Component(
|
||||
{
|
||||
product_id => $def_product->id,
|
||||
name => $params->{"moved-default-component"}
|
||||
product => $def_product,
|
||||
name => $params->{"moved-default-component"}
|
||||
})
|
||||
|| Error("Cannot import these bugs because an invalid default
|
||||
component was defined for the target db."
|
||||
|
@ -622,8 +622,8 @@ sub process_bug {
|
|||
new Bugzilla::Product( { name => $params->{"moved-default-product"} } );
|
||||
my $def_component = new Bugzilla::Component(
|
||||
{
|
||||
product_id => $def_product->id,
|
||||
name => $params->{"moved-default-component"}
|
||||
product => $def_product,
|
||||
name => $params->{"moved-default-component"}
|
||||
}
|
||||
);
|
||||
my $product;
|
||||
|
@ -643,8 +643,8 @@ sub process_bug {
|
|||
if ( defined $bug_fields{'component'} ) {
|
||||
$component = new Bugzilla::Component(
|
||||
{
|
||||
product_id => $product->id,
|
||||
name => $bug_fields{'component'}
|
||||
product => $product,
|
||||
name => $bug_fields{'component'}
|
||||
}
|
||||
);
|
||||
unless ($component) {
|
||||
|
|
|
@ -325,6 +325,11 @@
|
|||
|
||||
[% ELSIF error == "protection_violation" %]
|
||||
The function <code>[% function FILTER html %]</code> was called
|
||||
|
||||
[% IF argument %]
|
||||
with the argument <code>[% argument FILTER html %]</code>
|
||||
[% END %]
|
||||
|
||||
from
|
||||
|
||||
[% IF caller %]
|
||||
|
|
Загрузка…
Ссылка в новой задаче