Commit a128f843 authored by Christian Legnitto's avatar Christian Legnitto Committed by Max Kanat-Alexander

Bug 590334: Change Bug.pm to use the comment object (Bugzilla::Comment)

when creating or updating bug comment r=mkanat, a=mkanat
parent 2b8ade66
......@@ -17,6 +17,7 @@
# All rights reserved.
#
# Contributor(s): James Robson <arbingersys@gmail.com>
# Christian Legnitto <clegnitto@mozilla.com>
use strict;
......@@ -50,6 +51,7 @@ use constant DB_COLUMNS => qw(
);
use constant UPDATE_COLUMNS => qw(
isprivate
type
extra_data
);
......@@ -62,12 +64,21 @@ use constant ID_FIELD => 'comment_id';
use constant LIST_ORDER => 'bug_when, comment_id';
use constant VALIDATORS => {
extra_data => \&_check_extra_data,
type => \&_check_type,
bug_id => \&_check_bug_id,
who => \&_check_who,
bug_when => \&_check_bug_when,
work_time => \&_check_work_time,
thetext => \&_check_thetext,
isprivate => \&_check_isprivate,
extra_data => \&_check_extra_data,
type => \&_check_type,
};
use constant VALIDATOR_DEPENDENCIES => {
extra_data => ['type'],
bug_id => ['who'],
work_time => ['who'],
isprivate => ['who'],
};
#########################
......@@ -157,12 +168,9 @@ sub body_full {
# Mutators #
############
sub set_extra_data { $_[0]->set('extra_data', $_[1]); }
sub set_type {
my ($self, $type) = @_;
$self->set('type', $type);
}
sub set_is_private { $_[0]->set('isprivate', $_[1]); }
sub set_type { $_[0]->set('type', $_[1]); }
sub set_extra_data { $_[0]->set('extra_data', $_[1]); }
##############
# Validators #
......@@ -209,6 +217,87 @@ sub _check_type {
return $type;
}
sub _check_bug_id {
my ($invocant, $bug_id) = @_;
ThrowCodeError('param_required', {function => 'Bugzilla::Comment->create',
param => 'bug_id'}) unless $bug_id;
my $bug;
if (blessed $bug_id) {
# We got a bug object passed in, use it
$bug = $bug_id;
$bug->check_is_visible;
}
else {
# We got a bug id passed in, check it and get the bug object
$bug = Bugzilla::Bug->check({ id => $bug_id });
}
# Make sure the user can edit the product
Bugzilla->user->can_edit_product($bug->{product_id});
# Make sure the user can comment
my $privs;
$bug->check_can_change_field('longdesc', 0, 1, \$privs)
|| ThrowUserError('illegal_change',
{ field => 'longdesc', privs => $privs });
return $bug->id;
}
sub _check_who {
my ($invocant, $who) = @_;
Bugzilla->login(LOGIN_REQUIRED);
return Bugzilla->user->id;
}
sub _check_bug_when {
my ($invocant, $when) = @_;
# Make sure the timestamp is defined, default to a timestamp from the db
if (!defined $when) {
$when = Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
}
# Make sure the timestamp parses
if (!datetime_from($when)) {
ThrowCodeError('invalid_timestamp', { timestamp => $when });
}
return $when;
}
sub _check_work_time {
my ($invocant, $value_in, $field, $params) = @_;
# Call down to Bugzilla::Object, letting it know negative
# values are ok
return $invocant->check_time( $value_in, $field, $params, 1);
}
sub _check_thetext {
my ($invocant, $thetext) = @_;
ThrowCodeError('param_required',{function => 'Bugzilla::Comment->create',
param => 'thetext'}) unless defined $thetext;
# Remove any trailing whitespace. Leading whitespace could be
# a valid part of the comment.
$thetext =~ s/\s*$//s;
$thetext =~ s/\r\n?/\n/g; # Get rid of \r.
ThrowUserError('comment_too_long') if length($thetext) > MAX_COMMENT_LENGTH;
return $thetext;
}
sub _check_isprivate {
my ($invocant, $isprivate) = @_;
if ($isprivate && !Bugzilla->user->is_insider) {
ThrowUserError('user_not_insider');
}
return $isprivate ? 1 : 0;
}
sub count {
my ($self) = @_;
......
......@@ -30,6 +30,7 @@ use Bugzilla::Error;
use Date::Parse;
use List::MoreUtils qw(part);
use Scalar::Util qw(blessed);
use constant NAME_FIELD => 'name';
use constant ID_FIELD => 'id';
......@@ -462,13 +463,21 @@ sub check_required_create_fields {
}
sub run_create_validators {
my ($class, $params) = @_;
my ($class, $params, $options) = @_;
my $validators = $class->_get_validators;
my %field_values = %$params;
# Make a hash skiplist for easier searching later
my %skip_list = map { $_ => 1 } @{ $options->{skip} || [] };
# Get the sorted field names
my @sorted_names = $class->_sort_by_dep(keys %field_values);
foreach my $field (@sorted_names) {
# Remove the skipped names
my @unskipped = grep { !$skip_list{$_} } @sorted_names;
foreach my $field (@unskipped) {
my $value;
if (exists $validators->{$field}) {
my $validator = $validators->{$field};
......@@ -527,10 +536,54 @@ sub get_all {
sub check_boolean { return $_[1] ? 1 : 0 }
sub check_time {
my ($invocant, $value, $field, $params, $allow_negative) = @_;
# If we don't have a current value default to zero
my $current = blessed($invocant) ? $invocant->{$field}
: 0;
$current ||= 0;
# Don't let the user set the value if they aren't a timetracker
return $current unless Bugzilla->user->is_timetracker;
# Get the new value or zero if it isn't defined
$value = trim($value) || 0;
# Make sure the new value is well formed
_validate_time($value, $field, $allow_negative);
return $value;
}
###################
# General Helpers #
###################
sub _validate_time {
my ($time, $field, $allow_negative) = @_;
# regexp verifies one or more digits, optionally followed by a period and
# zero or more digits, OR we have a period followed by one or more digits
# (allow negatives, though, so people can back out errors in time reporting)
if ($time !~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/) {
ThrowUserError("number_not_numeric",
{field => $field, num => "$time"});
}
# Callers can optionally allow negative times
if ( ($time < 0) && !$allow_negative ) {
ThrowUserError("number_too_small",
{field => $field, num => "$time", min_num => "0"});
}
if ($time > 99999.99) {
ThrowUserError("number_too_large",
{field => $field, num => "$time", max_num => "99999.99"});
}
}
# Sorts fields according to VALIDATOR_DEPENDENCIES. This is not a
# traditional topological sort, because a "dependency" does not
# *have* to be in the list--it just has to be earlier than its dependent
......@@ -1036,7 +1089,11 @@ Description: Runs the validation of input parameters for L</create>.
of their input parameters. This method is B<only> called
by L</create>.
Params: The same as L</create>.
Params: C<$params> - hashref - A value to put in each database
field for this object.
C<$options> - hashref - Processing options. Currently
the only option supported is B<skip>, which can be
used to specify a list of fields to not validate.
Returns: A hash, in a similar format as C<$params>, except that
these are the values to be inserted into the database,
......
......@@ -70,6 +70,7 @@ use lib qw(. lib);
use Bugzilla;
use Bugzilla::Object;
use Bugzilla::Bug;
use Bugzilla::Product;
use Bugzilla::Version;
......@@ -763,7 +764,7 @@ sub process_bug {
push( @query, "deadline" );
if ( defined $bug_fields{'estimated_time'} ) {
eval {
Bugzilla::Bug::ValidateTime($bug_fields{'estimated_time'}, "e");
Bugzilla::Object::_validate_time($bug_fields{'estimated_time'}, "e");
};
if (!$@){
push( @values, $bug_fields{'estimated_time'} );
......@@ -772,7 +773,7 @@ sub process_bug {
}
if ( defined $bug_fields{'remaining_time'} ) {
eval {
Bugzilla::Bug::ValidateTime($bug_fields{'remaining_time'}, "r");
Bugzilla::Object::_validate_time($bug_fields{'remaining_time'}, "r");
};
if (!$@){
push( @values, $bug_fields{'remaining_time'} );
......@@ -781,7 +782,7 @@ sub process_bug {
}
if ( defined $bug_fields{'actual_time'} ) {
eval {
Bugzilla::Bug::ValidateTime($bug_fields{'actual_time'}, "a");
Bugzilla::Object::_validate_time($bug_fields{'actual_time'}, "a");
};
if ($@){
$bug_fields{'actual_time'} = 0.0;
......
......@@ -236,6 +236,10 @@
The series_id [% series_id FILTER html %] is not valid. It may be that
this series has been deleted.
[% ELSIF error == "invalid_timestamp" %]
The entered timestamp <code>[% timestamp FILTER html %]</code> could not
be parsed into a valid date and time.
[% ELSIF error == "invalid_webservergroup" %]
There is no such group: [% group FILTER html %]. Check your $webservergroup
setting in [% constants.bz_locations.localconfig FILTER html %].
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment