diff options
Diffstat (limited to 'Bugzilla/Milestone.pm')
-rw-r--r-- | Bugzilla/Milestone.pm | 296 |
1 files changed, 151 insertions, 145 deletions
diff --git a/Bugzilla/Milestone.pm b/Bugzilla/Milestone.pm index cf7e3e35f..815a111f8 100644 --- a/Bugzilla/Milestone.pm +++ b/Bugzilla/Milestone.pm @@ -25,140 +25,140 @@ use Scalar::Util qw(blessed); use constant DEFAULT_SORTKEY => 0; -use constant DB_TABLE => 'milestones'; +use constant DB_TABLE => 'milestones'; use constant NAME_FIELD => 'value'; use constant LIST_ORDER => 'sortkey, value'; use constant DB_COLUMNS => qw( - id - value - product_id - sortkey - isactive + id + value + product_id + sortkey + isactive ); -use constant REQUIRED_FIELD_MAP => { - product_id => 'product', -}; +use constant REQUIRED_FIELD_MAP => {product_id => 'product',}; use constant UPDATE_COLUMNS => qw( - value - sortkey - isactive + value + sortkey + isactive ); use constant VALIDATORS => { - product => \&_check_product, - sortkey => \&_check_sortkey, - value => \&_check_value, - isactive => \&Bugzilla::Object::check_boolean, + product => \&_check_product, + sortkey => \&_check_sortkey, + value => \&_check_value, + isactive => \&Bugzilla::Object::check_boolean, }; -use constant VALIDATOR_DEPENDENCIES => { - value => ['product'], -}; +use constant VALIDATOR_DEPENDENCIES => {value => ['product'],}; ################################ sub new { - my $class = shift; - my $param = shift; - my $dbh = Bugzilla->dbh; - - my $product; - if (ref $param and !defined $param->{id}) { - $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"}); - } - - my $condition = 'product_id = ? AND value = ?'; - my @values = ($product->id, $name); - $param = { condition => $condition, values => \@values }; + my $class = shift; + my $param = shift; + my $dbh = Bugzilla->dbh; + + my $product; + if (ref $param and !defined $param->{id}) { + $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"}); + } + + my $condition = 'product_id = ? AND value = ?'; + my @values = ($product->id, $name); + $param = {condition => $condition, values => \@values}; + } - unshift @_, $param; - return $class->SUPER::new(@_); + unshift @_, $param; + return $class->SUPER::new(@_); } sub run_create_validators { - my $class = shift; - my $params = $class->SUPER::run_create_validators(@_); - my $product = delete $params->{product}; - $params->{product_id} = $product->id; - return $params; + my $class = shift; + my $params = $class->SUPER::run_create_validators(@_); + my $product = delete $params->{product}; + $params->{product_id} = $product->id; + return $params; } sub update { - my $self = shift; - my $dbh = Bugzilla->dbh; - - $dbh->bz_start_transaction(); - my $changes = $self->SUPER::update(@_); - - if (exists $changes->{value}) { - # The milestone value is stored in the bugs table instead of its ID. - $dbh->do('UPDATE bugs SET target_milestone = ? - WHERE target_milestone = ? AND product_id = ?', - undef, ($self->name, $changes->{value}->[0], $self->product_id)); - - # The default milestone also stores the value instead of the ID. - $dbh->do('UPDATE products SET defaultmilestone = ? - WHERE id = ? AND defaultmilestone = ?', - undef, ($self->name, $self->product_id, $changes->{value}->[0])); - Bugzilla->memcached->clear({ table => 'products', id => $self->product_id }); - } - $dbh->bz_commit_transaction(); - Bugzilla->memcached->clear_config(); - - return $changes; + my $self = shift; + my $dbh = Bugzilla->dbh; + + $dbh->bz_start_transaction(); + my $changes = $self->SUPER::update(@_); + + if (exists $changes->{value}) { + + # The milestone value is stored in the bugs table instead of its ID. + $dbh->do( + 'UPDATE bugs SET target_milestone = ? + WHERE target_milestone = ? AND product_id = ?', undef, + ($self->name, $changes->{value}->[0], $self->product_id) + ); + + # The default milestone also stores the value instead of the ID. + $dbh->do( + 'UPDATE products SET defaultmilestone = ? + WHERE id = ? AND defaultmilestone = ?', undef, + ($self->name, $self->product_id, $changes->{value}->[0]) + ); + Bugzilla->memcached->clear({table => 'products', id => $self->product_id}); + } + $dbh->bz_commit_transaction(); + Bugzilla->memcached->clear_config(); + + return $changes; } sub remove_from_db { - my $self = shift; - my $dbh = Bugzilla->dbh; + my $self = shift; + my $dbh = Bugzilla->dbh; - $dbh->bz_start_transaction(); + $dbh->bz_start_transaction(); - # The default milestone cannot be deleted. - if ($self->name eq $self->product->default_milestone) { - ThrowUserError('milestone_is_default', { milestone => $self }); - } + # The default milestone cannot be deleted. + if ($self->name eq $self->product->default_milestone) { + ThrowUserError('milestone_is_default', {milestone => $self}); + } + + if ($self->bug_count) { - if ($self->bug_count) { - # We don't want to delete bugs when deleting a milestone. - # Bugs concerned are reassigned to the default milestone. - my $bug_ids = - $dbh->selectcol_arrayref('SELECT bug_id FROM bugs + # We don't want to delete bugs when deleting a milestone. + # Bugs concerned are reassigned to the default milestone. + my $bug_ids = $dbh->selectcol_arrayref( + 'SELECT bug_id FROM bugs WHERE product_id = ? AND target_milestone = ?', - undef, ($self->product->id, $self->name)); - - my $timestamp = $dbh->selectrow_array('SELECT NOW()'); - - $dbh->do('UPDATE bugs SET target_milestone = ?, delta_ts = ? - WHERE ' . $dbh->sql_in('bug_id', $bug_ids), - undef, ($self->product->default_milestone, $timestamp)); - - require Bugzilla::Bug; - import Bugzilla::Bug qw(LogActivityEntry); - foreach my $bug_id (@$bug_ids) { - LogActivityEntry($bug_id, 'target_milestone', - $self->name, - $self->product->default_milestone, - Bugzilla->user->id, $timestamp); - } + undef, ($self->product->id, $self->name) + ); + + my $timestamp = $dbh->selectrow_array('SELECT NOW()'); + + $dbh->do( + 'UPDATE bugs SET target_milestone = ?, delta_ts = ? + WHERE ' . $dbh->sql_in('bug_id', $bug_ids), undef, + ($self->product->default_milestone, $timestamp) + ); + + require Bugzilla::Bug; + import Bugzilla::Bug qw(LogActivityEntry); + foreach my $bug_id (@$bug_ids) { + LogActivityEntry($bug_id, 'target_milestone', $self->name, + $self->product->default_milestone, + Bugzilla->user->id, $timestamp); } - $self->SUPER::remove_from_db(); + } + $self->SUPER::remove_from_db(); - $dbh->bz_commit_transaction(); + $dbh->bz_commit_transaction(); } ################################ @@ -166,78 +166,84 @@ sub remove_from_db { ################################ sub _check_value { - my ($invocant, $name, undef, $params) = @_; - my $product = blessed($invocant) ? $invocant->product : $params->{product}; - - $name = trim($name); - $name || ThrowUserError('milestone_blank_name'); - if (length($name) > MAX_MILESTONE_SIZE) { - ThrowUserError('milestone_name_too_long', {name => $name}); - } - - my $milestone = new Bugzilla::Milestone({product => $product, name => $name}); - if ($milestone && (!ref $invocant || $milestone->id != $invocant->id)) { - ThrowUserError('milestone_already_exists', { name => $milestone->name, - product => $product->name }); - } - return $name; + my ($invocant, $name, undef, $params) = @_; + my $product = blessed($invocant) ? $invocant->product : $params->{product}; + + $name = trim($name); + $name || ThrowUserError('milestone_blank_name'); + if (length($name) > MAX_MILESTONE_SIZE) { + ThrowUserError('milestone_name_too_long', {name => $name}); + } + + my $milestone = new Bugzilla::Milestone({product => $product, name => $name}); + if ($milestone && (!ref $invocant || $milestone->id != $invocant->id)) { + ThrowUserError('milestone_already_exists', + {name => $milestone->name, product => $product->name}); + } + return $name; } sub _check_sortkey { - my ($invocant, $sortkey) = @_; - - # Keep a copy in case detaint_signed() clears the sortkey - my $stored_sortkey = $sortkey; - - if (!detaint_signed($sortkey) || $sortkey < MIN_SMALLINT || $sortkey > MAX_SMALLINT) { - ThrowUserError('milestone_sortkey_invalid', {sortkey => $stored_sortkey}); - } - return $sortkey; + my ($invocant, $sortkey) = @_; + + # Keep a copy in case detaint_signed() clears the sortkey + my $stored_sortkey = $sortkey; + + if ( !detaint_signed($sortkey) + || $sortkey < MIN_SMALLINT + || $sortkey > MAX_SMALLINT) + { + ThrowUserError('milestone_sortkey_invalid', {sortkey => $stored_sortkey}); + } + return $sortkey; } sub _check_product { - my ($invocant, $product) = @_; - $product || ThrowCodeError('param_required', - { function => "$invocant->create", param => "product" }); - return Bugzilla->user->check_can_admin_product($product->name); + my ($invocant, $product) = @_; + $product + || ThrowCodeError('param_required', + {function => "$invocant->create", param => "product"}); + return Bugzilla->user->check_can_admin_product($product->name); } ################################ # Methods ################################ -sub set_name { $_[0]->set('value', $_[1]); } -sub set_sortkey { $_[0]->set('sortkey', $_[1]); } +sub set_name { $_[0]->set('value', $_[1]); } +sub set_sortkey { $_[0]->set('sortkey', $_[1]); } sub set_is_active { $_[0]->set('isactive', $_[1]); } sub bug_count { - my $self = shift; - my $dbh = Bugzilla->dbh; + my $self = shift; + my $dbh = Bugzilla->dbh; - if (!defined $self->{'bug_count'}) { - $self->{'bug_count'} = $dbh->selectrow_array(q{ + if (!defined $self->{'bug_count'}) { + $self->{'bug_count'} = $dbh->selectrow_array( + q{ SELECT COUNT(*) FROM bugs - WHERE product_id = ? AND target_milestone = ?}, - undef, $self->product_id, $self->name) || 0; - } - return $self->{'bug_count'}; + WHERE product_id = ? AND target_milestone = ?}, undef, $self->product_id, + $self->name + ) || 0; + } + return $self->{'bug_count'}; } ################################ ##### Accessors ###### ################################ -sub name { return $_[0]->{'value'}; } +sub name { return $_[0]->{'value'}; } sub product_id { return $_[0]->{'product_id'}; } -sub sortkey { return $_[0]->{'sortkey'}; } -sub is_active { return $_[0]->{'isactive'}; } +sub sortkey { return $_[0]->{'sortkey'}; } +sub is_active { return $_[0]->{'isactive'}; } sub product { - my $self = shift; + my $self = shift; - require Bugzilla::Product; - $self->{'product'} ||= new Bugzilla::Product($self->product_id); - return $self->{'product'}; + require Bugzilla::Product; + $self->{'product'} ||= new Bugzilla::Product($self->product_id); + return $self->{'product'}; } 1; |