X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Flib%2FRT%2FCustomField_Overlay.pm;h=c6fa1851f5321723dcb652fd9422a148acbf8e9c;hb=9e9c755d167db759e53c2378214fed057fad0661;hp=e2342e946b8e6d1ec382216550735beaf96c4439;hpb=01352af8e44b7eb70b2b587ca43ab7ca946f038d;p=freeside.git diff --git a/rt/lib/RT/CustomField_Overlay.pm b/rt/lib/RT/CustomField_Overlay.pm index e2342e946..c6fa1851f 100644 --- a/rt/lib/RT/CustomField_Overlay.pm +++ b/rt/lib/RT/CustomField_Overlay.pm @@ -102,6 +102,11 @@ our %FieldTypes = ( 'Select date', # loc 'Select up to [_1] dates', # loc ], + TimeValue => [ + 'Enter multiple time values (UNSUPPORTED)', + 'Enter a time value', + 'Enter [_1] time values (UNSUPPORTED)', + ], ); @@ -261,6 +266,10 @@ sub Create { $self->SetBasedOn( $args{'BasedOn'} ); } + if ( exists $args{'UILocation'} ) { + $self->SetUILocation( $args{'UILocation'} ); + } + return ($rv, $msg) unless exists $args{'Queue'}; # Compat code -- create a new ObjectCustomField mapping @@ -329,10 +338,12 @@ sub LoadByName { } # if we're looking for a queue by name, make it a number - if ( defined $args{'Queue'} && $args{'Queue'} =~ /\D/ ) { + if ( defined $args{'Queue'} && ($args{'Queue'} =~ /\D/ || !$self->ContextObject) ) { my $QueueObj = RT::Queue->new( $self->CurrentUser ); $QueueObj->Load( $args{'Queue'} ); $args{'Queue'} = $QueueObj->Id; + $self->SetContextObject( $QueueObj ) + unless $self->ContextObject; } # XXX - really naive implementation. Slow. - not really. still just one query @@ -390,6 +401,8 @@ sub Values { # if the user has no rights, return an empty object if ( $self->id && $self->CurrentUserHasRight( 'SeeCustomField') ) { $cf_values->LimitToCustomField( $self->Id ); + } else { + $cf_values->Limit( FIELD => 'id', VALUE => 0, SUBCLAUSE => 'acl' ); } return ($cf_values); } @@ -735,7 +748,77 @@ sub ContextObject { my $self = shift; return $self->{'context_object'}; } - + +sub ValidContextType { + my $self = shift; + my $class = shift; + + my %valid; + $valid{$_}++ for split '-', $self->LookupType; + delete $valid{'RT::Transaction'}; + + return $valid{$class}; +} + +=head2 LoadContextObject + +Takes an Id for a Context Object and loads the right kind of RT::Object +for this particular Custom Field (based on the LookupType) and returns it. +This is a good way to ensure you don't try to use a Queue as a Context +Object on a User Custom Field. + +=cut + +sub LoadContextObject { + my $self = shift; + my $type = shift; + my $contextid = shift; + + unless ( $self->ValidContextType($type) ) { + RT->Logger->debug("Invalid ContextType $type for Custom Field ".$self->Id); + return; + } + + my $context_object = $type->new( $self->CurrentUser ); + my ($id, $msg) = $context_object->LoadById( $contextid ); + unless ( $id ) { + RT->Logger->debug("Invalid ContextObject id: $msg"); + return; + } + return $context_object; +} + +=head2 ValidateContextObject + +Ensure that a given ContextObject applies to this Custom Field. +For custom fields that are assigned to Queues or to Classes, this checks that the Custom +Field is actually applied to that objects. For Global Custom Fields, it returns true +as long as the Object is of the right type, because you may be using +your permissions on a given Queue of Class to see a Global CF. +For CFs that are only applied Globally, you don't need a ContextObject. + +=cut + +sub ValidateContextObject { + my $self = shift; + my $object = shift; + + return 1 if $self->IsApplied(0); + + # global only custom fields don't have objects + # that should be used as context objects. + return if $self->ApplyGlobally; + + # Otherwise, make sure we weren't passed a user object that we're + # supposed to treat as a queue. + return unless $self->ValidContextType(ref $object); + + # Check that it is applied correctly + my ($applied_to) = grep {ref($_) eq $self->RecordClassFromLookupType} ($object, $object->ACLEquivalenceObjects); + return unless $applied_to; + return $self->IsApplied($applied_to->id); +} + # {{{ sub _Set sub _Set { @@ -835,7 +918,7 @@ Returns an array of all possible composite values for custom fields. sub TypeComposites { my $self = shift; - return grep !/(?:[Tt]ext|Combobox|Date)-0/, map { ("$_-1", "$_-0") } $self->Types; + return grep !/(?:[Tt]ext|Combobox|Date|TimeValue)-0/, map { ("$_-1", "$_-0") } $self->Types; } =head2 SetLookupType @@ -1426,12 +1509,13 @@ sub SetBasedOn { unless defined $value and length $value; my $cf = RT::CustomField->new( $self->CurrentUser ); + $cf->SetContextObject( $self->ContextObject ); $cf->Load( ref $value ? $value->Id : $value ); return (0, "Permission denied") unless $cf->Id && $cf->CurrentUserHasRight('SeeCustomField'); - return $self->AddAttribute( + return $self->SetAttribute( Name => "BasedOn", Description => "Custom field whose CF we depend on", Content => $cf->Id, @@ -1441,10 +1525,28 @@ sub SetBasedOn { sub BasedOnObj { my $self = shift; my $obj = RT::CustomField->new( $self->CurrentUser ); + $obj->SetContextObject( $self->ContextObject ); my $attribute = $self->FirstAttribute("BasedOn"); $obj->Load($attribute->Content) if defined $attribute; return $obj; } +sub UILocation { + my $self = shift; + my $tag = $self->FirstAttribute( 'UILocation' ); + return $tag ? $tag->Content : ''; +} + +sub SetUILocation { + my $self = shift; + my $tag = shift; + if ( $tag ) { + return $self->SetAttribute( Name => 'UILocation', Content => $tag ); + } + else { + return $self->DeleteAttribute('UILocation'); + } +} + 1;