From b63fd277afedfb5d101ce4700058609e81199855 Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Mon, 4 Sep 2006 23:19:07 +0000 Subject: Bug 349741: Make Bugzilla::Bug able to do basic bug creation, and have post_bug.cgi use it Patch By Max Kanat-Alexander r=bkor, a=myk --- Bugzilla/Bug.pm | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 157 insertions(+), 9 deletions(-) (limited to 'Bugzilla/Bug.pm') diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 8c61a657b..642a71d3f 100755 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -96,6 +96,34 @@ sub DB_COLUMNS { Bugzilla->custom_field_names; } +use constant REQUIRED_CREATE_FIELDS => qw( + bug_severity + component + creation_ts + op_sys + priority + product + rep_platform + short_desc + version +); + +# There are also other, more complex validators that are called +# from run_create_validators. +use constant VALIDATORS => { + alias => \&_check_alias, + bug_file_loc => \&_check_bug_file_loc, + bug_severity => \&_check_bug_severity, + deadline => \&_check_deadline, + estimated_time => \&_check_estimated_time, + op_sys => \&_check_op_sys, + priority => \&_check_priority, + remaining_time => \&_check_remaining_time, + rep_platform => \&_check_rep_platform, + short_desc => \&_check_short_desc, + status_whiteboard => \&_check_status_whiteboard, +}; + # Used in LogActivityEntry(). Gives the max length of lines in the # activity table. use constant MAX_LINE_LENGTH => 254; @@ -157,6 +185,79 @@ sub new { return $self; } +# Docs for create() (there's no POD in this file yet, but we very +# much need this documented right now): +# +# The same as Bugzilla::Object->create. Parameters are only required +# if they say so below. +# +# Params: +# +# C - B The name of the product this bug is being +# filed against. +# C - B The name of the component this bug is being +# filed against. +# +# C - B The severity for the bug, a string. +# C - B A SQL timestamp for when the bug was created. +# C - B A summary for the bug. +# C - B The OS the bug was found against. +# C - B The initial priority for the bug. +# C - B The platform the bug was found against. +# C - B The version of the product the bug was found in. +# +# C - An alias for this bug. Will be ignored if C +# is off. +# C - When this bug is expected to be fixed. +# C - A string. +# C - The initial status of the bug, a string. +# C - The URL field. +# +# C - The full login name of the user who the bug is +# initially assigned to. +# C - The full login name of the QA Contact for this bug. +# Will be ignored if C is off. +# +# C - For time-tracking. Will be ignored if +# C is not set, or if the current +# user is not a member of the timetrackinggroup. +# C - For time-tracking. Will be ignored for the same +# reasons as C. + +sub run_create_validators { + my $class = shift; + my $params = shift; + + my $product = _check_product($params->{product}); + $params->{product_id} = $product->id; + delete $params->{product}; + + ($params->{bug_status}, $params->{everconfirmed}) + = _check_bug_status($product, $params->{bug_status}); + + $params->{target_milestone} = _check_target_milestone($product, + $params->{target_milestone}); + + $params->{version} = _check_version($product, $params->{version}); + + my $component = _check_component($product, $params->{component}); + $params->{component_id} = $component->id; + delete $params->{component}; + + $params->{assigned_to} = + _check_assigned_to($component, $params->{assigned_to}); + $params->{qa_contact} = + _check_qa_contact($component, $params->{qa_contact}); + # Callers cannot set Reporter, currently. + $params->{reporter} = Bugzilla->user->id; + + $params->{delta_ts} = $params->{creation_ts}; + $params->{remaining_time} = $params->{estimated_time}; + + unshift @_, $params; + return $class->SUPER::run_create_validators(@_); +} + # This is the correct way to delete bugs from the DB. # No bug should be deleted from anywhere else except from here. # @@ -233,12 +334,13 @@ sub remove_from_db { sub _check_alias { my ($alias) = @_; $alias = trim($alias); - ValidateBugAlias($alias) if (defined $alias && $alias ne ''); + return undef if (!Bugzilla->params->{'usebugaliases'} || !$alias); + ValidateBugAlias($alias); return $alias; } sub _check_assigned_to { - my ($name, $component) = @_; + my ($component, $name) = @_; my $user = Bugzilla->user; $name = trim($name); @@ -254,9 +356,6 @@ sub _check_assigned_to { sub _check_bug_file_loc { my ($url) = @_; - if (!defined $url) { - ThrowCodeError('undefined_field', { field => 'bug_file_loc' }); - } # If bug_file_loc is "http://", the default, use an empty value instead. $url = '' if $url eq 'http://'; return $url; @@ -270,7 +369,7 @@ sub _check_bug_severity { } sub _check_bug_status { - my ($status, $product) = @_; + my ($product, $status) = @_; my $user = Bugzilla->user; my @valid_statuses = VALID_ENTRY_STATUS; @@ -293,7 +392,7 @@ sub _check_bug_status { shift @valid_statuses if !$product->votes_to_confirm; check_field('bug_status', $status, \@valid_statuses); - return $status; + return ($status, $status eq 'UNCONFIRMED' ? 0 : 1); } sub _check_cc { @@ -331,7 +430,7 @@ sub _check_comment { } sub _check_component { - my ($name, $product) = @_; + my ($product, $name) = @_; $name = trim($name); $name || ThrowUserError("require_component"); my $obj = Bugzilla::Component::check_component($product, $name); @@ -341,6 +440,18 @@ sub _check_component { return $obj; } +sub _check_deadline { + my ($date) = @_; + $date = trim($date); + my $tt_group = Bugzilla->params->{"timetrackinggroup"}; + return undef unless $date && $tt_group + && Bugzilla->user->in_group($tt_group); + validate_date($date) + || ThrowUserError('illegal_date', { date => $date, + format => 'YYYY-MM-DD' }); + return $date; +} + # Takes two comma/space-separated strings and returns arrayrefs # of valid bug IDs. sub _check_dependencies { @@ -370,6 +481,10 @@ sub _check_dependencies { return ($deps{'dependson'}, $deps{'blocked'}); } +sub _check_estimated_time { + return _check_time($_[0], 'estimated_time'); +} + sub _check_keywords { my ($keyword_string) = @_; $keyword_string = trim($keyword_string); @@ -417,6 +532,10 @@ sub _check_priority { return $priority; } +sub _check_remaining_time { + return _check_time($_[0], 'remaining_time'); +} + sub _check_rep_platform { my ($platform) = @_; $platform = trim($platform); @@ -435,6 +554,8 @@ sub _check_short_desc { return $short_desc; } +sub _check_status_whiteboard { return defined $_[0] ? $_[0] : ''; } + # Unlike other checkers, this one doesn't return anything. sub _check_strict_isolation { my ($product, $cc_ids, $assignee_id, $qa_contact_id) = @_; @@ -466,10 +587,30 @@ sub _check_strict_isolation { } } +sub _check_target_milestone { + my ($product, $target) = @_; + $target = trim($target); + $target = $product->default_milestone if !defined $target; + check_field('target_milestone', $target, + [map($_->name, @{$product->milestones})]); + return $target; +} + +sub _check_time { + my ($time, $field) = @_; + my $tt_group = Bugzilla->params->{"timetrackinggroup"}; + return 0 unless $tt_group && Bugzilla->user->in_group($tt_group); + $time = trim($time) || 0; + ValidateTime($time, $field); + return $time; +} + sub _check_qa_contact { - my ($name, $component) = @_; + my ($component, $name) = @_; my $user = Bugzilla->user; + return undef unless Bugzilla->params->{'useqacontact'}; + $name = trim($name); my $id; @@ -483,6 +624,13 @@ sub _check_qa_contact { return $id; } +sub _check_version { + my ($product, $version) = @_; + $version = trim($version); + check_field('version', $version, [map($_->name, @{$product->versions})]); + return $version; +} + ##################################################################### # Class Accessors -- cgit v1.2.3-24-g4f1b