From 931bd3b651ccca832a618f7b28bbc35e503665d4 Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Fri, 3 Oct 2008 06:28:31 +0000 Subject: Bug 455632: Add Bugzilla::Field::Choice->create and have editvalues.cgi use it Patch By Max Kanat-Alexander r=bbaetz, a=mkanat --- Bugzilla/Bug.pm | 8 -- Bugzilla/Constants.pm | 4 + Bugzilla/Field.pm | 4 +- Bugzilla/Field/Choice.pm | 237 +++++++++++++++++++++++++++++------------------ Bugzilla/Status.pm | 55 ++++++++++- 5 files changed, 205 insertions(+), 103 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 1d12ee2cf..d620f222c 100644 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -54,7 +54,6 @@ use base qw(Bugzilla::Object Exporter); RemoveVotes CheckIfVotedConfirmed LogActivityEntry editable_bug_fields - SPECIAL_STATUS_WORKFLOW_ACTIONS ); ##################################################################### @@ -234,13 +233,6 @@ use constant MAX_LINE_LENGTH => 254; # Used in _check_comment(). Gives the max length allowed for a comment. use constant MAX_COMMENT_LENGTH => 65535; -use constant SPECIAL_STATUS_WORKFLOW_ACTIONS => qw( - none - duplicate - change_resolution - clearresolution -); - ##################################################################### sub new { diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index abe1fe248..601ea52b2 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -151,6 +151,7 @@ use File::Basename; MAX_PRODUCT_SIZE MAX_MILESTONE_SIZE MAX_COMPONENT_SIZE + MAX_FIELD_VALUE_SIZE MAX_FREETEXT_LENGTH ); @@ -427,6 +428,9 @@ use constant MAX_MILESTONE_SIZE => 20; # The longest component name allowed. use constant MAX_COMPONENT_SIZE => 64; +# The maximum length for values of -type field. my $field = new Bugzilla::Field({name => 'bug_status'}); - my $choice = new Bugzilla::Field::Choice({ field => $field, id => 1 }); - my $choice = new Bugzilla::Field::Choice({ field => $field, name => 'NEW' }); + my $choice = new Bugzilla::Field::Choice->type($field)->new(1); - my $choices = Bugzilla::Field::Choice->new_from_list([1,2,3], - { field => $field}); - my $choices = Bugzilla::Field::Choice->get_all({ field => $field }); - my $choices = Bugzilla::Field::Choice->match({ sortkey => 10, - field => $field }); + my $choices = Bugzilla::Field::Choice->type($field)->new_from_list([1,2,3]); + my $choices = Bugzilla::Field::Choice->type($field)->get_all(); + my $choices = Bugzilla::Field::Choice->type($field->match({ sortkey => 10 }); =head1 DESCRIPTION This is an implementation of L, but with a twist. -All the class methods require that you specify an additional C -argument, which is a L object that represents the -field whose value this is. +You can't call any class methods (such as C, C, etc.) +directly on C itself. Instead, you have to +call Ctype($field)> to get the class +you're going to instantiate, and then you call the methods on that. + +We do that because each field has its own database table for its values, so +each value type needs its own class. -You can look at the L to see where this extra C -argument goes in each function. +See the L for examples of how this works. =head1 METHODS +=head2 Class Factory + +In object-oriented design, a "class factory" is a method that picks +and returns the right class for you, based on an argument that you pass. + +=over + +=item C + +Takes a single argument, which is either the name of a field from the +C table, or a L object representing a field. + +Returns an appropriate subclass of C that you +can now call class methods on (like C, C, C, etc.) + +B: YOU CANNOT CALL CLASS METHODS ON C. You +must call C to get a class you can call methods on. + +=back + =head2 Accessors These are in addition to the standard L accessors. diff --git a/Bugzilla/Status.pm b/Bugzilla/Status.pm index f8b77331c..5f37974e7 100644 --- a/Bugzilla/Status.pm +++ b/Bugzilla/Status.pm @@ -22,13 +22,28 @@ use strict; package Bugzilla::Status; -use base qw(Bugzilla::Object Exporter); -@Bugzilla::Status::EXPORT = qw(BUG_STATE_OPEN is_open_state closed_bug_statuses); +use Bugzilla::Error; + +use base qw(Bugzilla::Field::Choice Exporter); +@Bugzilla::Status::EXPORT = qw( + BUG_STATE_OPEN + SPECIAL_STATUS_WORKFLOW_ACTIONS + + is_open_state + closed_bug_statuses +); ################################ ##### Initialization ##### ################################ +use constant SPECIAL_STATUS_WORKFLOW_ACTIONS => qw( + none + duplicate + change_resolution + clearresolution +); + use constant DB_TABLE => 'bug_status'; use constant DB_COLUMNS => qw( @@ -39,8 +54,24 @@ use constant DB_COLUMNS => qw( is_open ); -use constant NAME_FIELD => 'value'; -use constant LIST_ORDER => 'sortkey, value'; +sub VALIDATORS { + my $invocant = shift; + my $validators = $invocant->SUPER::VALIDATORS; + $validators->{is_open} = \&Bugzilla::Object::check_boolean; + $validators->{value} = \&_check_value; + return $validators; +} + +######################### +# Database Manipulation # +######################### + +sub create { + my $class = shift; + my $self = $class->SUPER::create(@_); + add_missing_bug_status_transitions(); + return $self; +} ############################### ##### Accessors #### @@ -51,6 +82,22 @@ sub sortkey { return $_[0]->{'sortkey'}; } sub is_active { return $_[0]->{'isactive'}; } sub is_open { return $_[0]->{'is_open'}; } +############## +# Validators # +############## + +sub _check_value { + my $invocant = shift; + my $value = $invocant->SUPER::_check_value(@_); + + if (grep { lc($value) eq lc($_) } SPECIAL_STATUS_WORKFLOW_ACTIONS) { + ThrowUserError('fieldvalue_reserved_word', + { field => $invocant->field, value => $value }); + } + return $value; +} + + ############################### ##### Methods #### ############################### -- cgit v1.2.3-24-g4f1b