3 # Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
5 # (Except where explictly superceded by other copyright notices)
7 # This work is made available to you under the terms of Version 2 of
8 # the GNU General Public License. A copy of that license should have
9 # been provided with this software, but in any event can be snarfed
12 # This work is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # General Public License for more details.
17 # Unless otherwise specified, all modifications, corrections or
18 # extensions to this work which alter its source code become the
19 # property of Best Practical Solutions, LLC when submitted for
20 # inclusion in the work.
25 no warnings qw(redefine);
27 use vars qw(@TYPES %TYPES);
29 use RT::CustomFieldValues;
30 use RT::TicketCustomFieldValues;
32 # Enumerate all valid types for this custom field
35 'SelectMultiple', # loc
36 'FreeformSingle', # loc
37 'FreeformMultiple', # loc
40 # Populate a hash of types of easier validation
41 for (@TYPES) { $TYPES{$_} = 1};
48 RT::CustomField_Overlay
58 =head2 Create PARAMHASH
60 Create takes a hash of values and creates a row in the database:
65 varchar(255) 'Description'.
67 smallint(6) 'Disabled'.
88 if ( ! $args{'Queue'} ) {
89 unless ( $self->CurrentUser->HasRight( Object => $RT::System, Right => 'AdminCustomFields') ) {
90 return ( 0, $self->loc('Permission Denied') );
94 my $queue = RT::Queue->new($self->CurrentUser);
95 $queue->Load($args{'Queue'});
97 return (0, $self->loc("Queue not found"));
99 unless ( $queue->CurrentUserHasRight('AdminCustomFields') ) {
100 return ( 0, $self->loc('Permission Denied') );
103 $self->SUPER::Create(
104 Name => $args{'Name'},
105 Type => $args{'Type'},
106 Queue => $args{'Queue'},
107 Description => $args{'Description'},
108 SortOrder => $args{'SortOrder'},
109 Disabled => $args{'Disabled'},
115 # {{{ sub LoadByNameAndQueue
117 =head2 LoadByNameAndQueue (Queue => QUEUEID, Name => NAME)
119 Loads the Custom field named NAME for Queue QUEUE. If QUEUE is 0,
120 loads a global custom field
124 # Compatibility for API change after 3.0 beta 1
125 *LoadNameAndQueue = \&LoadByNameAndQueue;
127 sub LoadByNameAndQueue {
135 return ( $self->LoadByCols( Name => $args{'Name'}, Queue => $args{'Queue'} ) );
141 # {{{ Dealing with custom field values
144 use_ok(RT::CustomField);
145 ok(my $cf = RT::CustomField->new($RT::SystemUser));
146 ok(my ($id, $msg)= $cf->Create( Name => 'TestingCF',
149 Description => 'A Testing custom field',
150 Type=> 'SelectSingle'), 'Created a global CustomField');
151 ok($id != 0, 'Global custom field correctly created');
152 ok ($cf->SingleValue);
153 ok($cf->Type eq 'SelectSingle');
155 ok($cf->SetType('SelectMultiple'));
156 ok($cf->Type eq 'SelectMultiple');
157 ok(!$cf->SingleValue );
158 ok(my ($bogus_val, $bogus_msg) = $cf->SetType('BogusType') , "Trying to set a custom field's type to a bogus type");
159 ok($bogus_val == 0, "Unable to set a custom field's type to a bogus type");
161 ok(my $bad_cf = RT::CustomField->new($RT::SystemUser));
162 ok(my ($bad_id, $bad_msg)= $cf->Create( Name => 'TestingCF-bad',
165 Description => 'A Testing custom field with a bogus Type',
166 Type=> 'SelectSingleton'), 'Created a global CustomField with a bogus type');
167 ok($bad_id == 0, 'Global custom field correctly decided to not create a cf with a bogus type ');
177 Create a new value for this CustomField. Takes a paramhash containing the elements Name, Description and SortOrder
181 ok(my $cf = RT::CustomField->new($RT::SystemUser));
184 ok(my ($val,$msg) = $cf->AddValue(Name => 'foo' , Description => 'TestCFValue', SortOrder => '6'));
186 ok (my ($delval, $delmsg) = $cf->DeleteValue($val));
195 my %args = ( Name => undef,
196 Description => undef,
200 unless ($self->CurrentUserHasRight('AdminCustomFields')) {
201 return (0, $self->loc('Permission Denied'));
204 unless ($args{'Name'}) {
205 return(0, $self->loc("Can't add a custom field value without a name"));
207 my $newval = RT::CustomFieldValue->new($self->CurrentUser);
208 return($newval->Create(
209 CustomField => $self->Id,
210 Name =>$args{'Name'},
211 Description => ($args{'Description'} || ''),
212 SortOrder => ($args{'SortOrder'} || '0')
221 =head2 DeleteValue ID
223 Deletes a value from this custom field by id.
225 Does not remove this value for any article which has had it selected
232 unless ($self->CurrentUserHasRight('AdminCustomFields')) {
233 return (0, $self->loc('Permission Denied'));
236 my $val_to_del = RT::CustomFieldValue->new($self->CurrentUser);
237 $val_to_del->Load($id);
238 unless ($val_to_del->Id) {
239 return (0, $self->loc("Couldn't find that value"));
241 unless ($val_to_del->CustomField == $self->Id) {
242 return (0, $self->loc("That is not a value for this custom field"));
245 my $retval = $val_to_del->Delete();
247 return ($retval, $self->loc("Custom field value deleted"));
249 return(0, $self->loc("Custom field value could not be deleted"));
259 Return a CustomFieldeValues object of all acceptable values for this Custom Field.
267 my $cf_values = RT::CustomFieldValues->new($self->CurrentUser);
268 if ( $self->__Value('Queue') == 0 || $self->CurrentUserHasRight( 'SeeQueue') ) {
269 $cf_values->LimitToCustomField($self->Id);
278 # {{{ Ticket related routines
280 # {{{ ValuesForTicket
282 =head2 ValuesForTicket TICKET
284 Returns a RT::TicketCustomFieldValues object of this Field's values for TICKET.
285 TICKET is a ticket id.
290 sub ValuesForTicket {
292 my $ticket_id = shift;
294 my $values = new RT::TicketCustomFieldValues($self->CurrentUser);
295 $values->LimitToCustomField($self->Id);
296 $values->LimitToTicket($ticket_id);
303 # {{{ AddValueForTicket
305 =head2 AddValueForTicket HASH
307 Adds a custom field value for a ticket. Takes a param hash of Ticket and Content
311 sub AddValueForTicket {
313 my %args = ( Ticket => undef,
317 my $newval = RT::TicketCustomFieldValue->new($self->CurrentUser);
318 my $val = $newval->Create(Ticket => $args{'Ticket'},
319 Content => $args{'Content'},
320 CustomField => $self->Id);
329 # {{{ DeleteValueForTicket
331 =head2 DeleteValueForTicket HASH
333 Adds a custom field value for a ticket. Takes a param hash of Ticket and Content
337 sub DeleteValueForTicket {
339 my %args = ( Ticket => undef,
343 my $oldval = RT::TicketCustomFieldValue->new($self->CurrentUser);
344 $oldval->LoadByTicketContentAndCustomField (Ticket => $args{'Ticket'},
345 Content => $args{'Content'},
346 CustomField => $self->Id );
347 # check ot make sure we found it
348 unless ($oldval->Id) {
349 return(0, $self->loc("Custom field value [_1] could not be found for custom field [_2]", $args{'Content'}, $self->Name));
353 my $ret = $oldval->Delete();
355 return(0, $self->loc("Custom field value could not be found"));
357 return(1, $self->loc("Custom field value deleted"));
365 =head2 ValidateQueue Queue
367 Make sure that the queue specified is a valid queue name
375 if ($id eq '0') { # 0 means "Global" null would _not_ be ok.
379 my $q = RT::Queue->new($RT::SystemUser);
394 Retuns an array of the types of CustomField that are supported
405 =head2 FriendlyType [TYPE]
407 Returns a localized human-readable version of the custom field type.
408 If a custom field type is specified as the parameter, the friendly type for that type will be returned
415 my $type = shift || $self->Type;
417 if ( $type eq 'SelectSingle' ) {
418 return ( $self->loc('Select one value') );
420 elsif ( $type eq 'SelectMultiple' ) {
421 return ( $self->loc('Select multiple values') );
423 elsif ( $type eq 'FreeformSingle' ) {
424 return ( $self->loc('Enter one value') );
426 elsif ( $type eq 'FreeformMultiple' ) {
427 return ( $self->loc('Enter multiple values') );
430 return ( $self->loc( $self->Type ) );
435 =head2 ValidateType TYPE
437 Takes a single string. returns true if that string is a value
442 ok(my $cf = RT::CustomField->new($RT::SystemUser));
443 ok($cf->ValidateType('SelectSingle'));
444 ok($cf->ValidateType('SelectMultiple'));
445 ok(!$cf->ValidateType('SelectFooMultiple'));
467 Returns true if this CustomField only accepts a single value.
468 Returns false if it accepts multiple values
474 if ($self->Type =~ /Single$/) {
484 # {{{ sub CurrentUserHasRight
486 =head2 CurrentUserHasRight RIGHT
488 Helper function to call the custom field's queue's CurrentUserHasRight with the passed in args.
492 sub CurrentUserHasRight {
495 # if there's no queue, we want to know about a global right
496 if ( ( !defined $self->__Value('Queue') ) || ( $self->__Value('Queue') == 0 ) ) {
497 return $self->CurrentUser->HasRight( Object => $RT::System, Right => $right);
499 return ( $self->QueueObj->CurrentUserHasRight($right) );
510 unless ( $self->CurrentUserHasRight('AdminCustomFields') ) {
511 return ( 0, $self->loc('Permission Denied') );
513 return ( $self->SUPER::_Set(@_) );
523 Takes the name of a table column.
524 Returns its value as a string, if the user passes an ACL check
533 # We need to expose the queue so that we can do things like ACL checks
534 if ( $field eq 'Queue') {
535 return ( $self->SUPER::_Value($field) );
539 #Anybody can see global custom fields, otherwise we need to do the rights check
540 unless ( $self->__Value('Queue') == 0 || $self->CurrentUserHasRight( 'SeeQueue') ) {
543 return ( $self->__Value($field) );
548 # {{{ sub SetDisabled
553 1 will cause this custom field to no longer be avaialble for tickets.
554 0 will re-enable this queue