diff options
author | Ivan Kohler <ivan@freeside.biz> | 2014-09-15 20:54:03 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2014-09-15 20:54:03 -0700 |
commit | bdc63b4ee68fb08d3ef281212bdffac2bc038717 (patch) | |
tree | 5f1c28e48cd03dced7204891ed108d6b85d9f47a /rt/lib/RT/CustomField.pm.orig | |
parent | ed1f84b4e8f626245995ecda5afcf83092c153b2 (diff) |
RT 4.0.22 - remove inadvertantly commited files
Diffstat (limited to 'rt/lib/RT/CustomField.pm.orig')
-rw-r--r-- | rt/lib/RT/CustomField.pm.orig | 2170 |
1 files changed, 0 insertions, 2170 deletions
diff --git a/rt/lib/RT/CustomField.pm.orig b/rt/lib/RT/CustomField.pm.orig deleted file mode 100644 index e71bbf78a..000000000 --- a/rt/lib/RT/CustomField.pm.orig +++ /dev/null @@ -1,2170 +0,0 @@ -# BEGIN BPS TAGGED BLOCK {{{ -# -# COPYRIGHT: -# -# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC -# <sales@bestpractical.com> -# -# (Except where explicitly superseded by other copyright notices) -# -# -# LICENSE: -# -# This work is made available to you under the terms of Version 2 of -# the GNU General Public License. A copy of that license should have -# been provided with this software, but in any event can be snarfed -# from www.gnu.org. -# -# This work is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301 or visit their web page on the internet at -# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. -# -# -# CONTRIBUTION SUBMISSION POLICY: -# -# (The following paragraph is not intended to limit the rights granted -# to you to modify and distribute this software under the terms of -# the GNU General Public License and is only of importance to you if -# you choose to contribute your changes and enhancements to the -# community by submitting them to Best Practical Solutions, LLC.) -# -# By intentionally submitting any modifications, corrections or -# derivatives to this work, or any other work intended for use with -# Request Tracker, to Best Practical Solutions, LLC, you confirm that -# you are the copyright holder for those contributions and you grant -# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, -# royalty-free, perpetual, license to use, copy, create derivative -# works based on those contributions, and sublicense and distribute -# those contributions and any derivatives thereof. -# -# END BPS TAGGED BLOCK }}} - -package RT::CustomField; - -use strict; -use warnings; - -use Scalar::Util 'blessed'; - -use base 'RT::Record'; - -sub Table {'CustomFields'} - - -use RT::CustomFieldValues; -use RT::ObjectCustomFields; -use RT::ObjectCustomFieldValues; - -our %FieldTypes = ( - Select => { - sort_order => 10, - selection_type => 1, - - labels => [ 'Select multiple values', # loc - 'Select one value', # loc - 'Select up to [_1] values', # loc - ], - - render_types => { - multiple => [ - - # Default is the first one - 'Select box', # loc - 'List', # loc - ], - single => [ 'Select box', # loc - 'Dropdown', # loc - 'List', # loc - ] - }, - - }, - Freeform => { - sort_order => 20, - selection_type => 0, - - labels => [ 'Enter multiple values', # loc - 'Enter one value', # loc - 'Enter up to [_1] values', # loc - ] - }, - Text => { - sort_order => 30, - selection_type => 0, - labels => [ - 'Fill in multiple text areas', # loc - 'Fill in one text area', # loc - 'Fill in up to [_1] text areas', # loc - ] - }, - Wikitext => { - sort_order => 40, - selection_type => 0, - labels => [ - 'Fill in multiple wikitext areas', # loc - 'Fill in one wikitext area', # loc - 'Fill in up to [_1] wikitext areas', # loc - ] - }, - - Image => { - sort_order => 50, - selection_type => 0, - labels => [ - 'Upload multiple images', # loc - 'Upload one image', # loc - 'Upload up to [_1] images', # loc - ] - }, - Binary => { - sort_order => 60, - selection_type => 0, - labels => [ - 'Upload multiple files', # loc - 'Upload one file', # loc - 'Upload up to [_1] files', # loc - ] - }, - - Combobox => { - sort_order => 70, - selection_type => 1, - labels => [ - 'Combobox: Select or enter multiple values', # loc - 'Combobox: Select or enter one value', # loc - 'Combobox: Select or enter up to [_1] values', # loc - ] - }, - Autocomplete => { - sort_order => 80, - selection_type => 1, - labels => [ - 'Enter multiple values with autocompletion', # loc - 'Enter one value with autocompletion', # loc - 'Enter up to [_1] values with autocompletion', # loc - ] - }, - - Date => { - sort_order => 90, - selection_type => 0, - labels => [ - 'Select multiple dates', # loc - 'Select date', # loc - 'Select up to [_1] dates', # loc - ] - }, - DateTime => { - sort_order => 100, - selection_type => 0, - labels => [ - 'Select multiple datetimes', # loc - 'Select datetime', # loc - 'Select up to [_1] datetimes', # loc - ] - }, - TimeValue => { - sort_order => 105, - selection_type => 0, - labels => [ - 'Enter multiple time values (UNSUPPORTED)', - 'Enter a time value', - 'Enter [_1] time values (UNSUPPORTED)', - ] - }, - - IPAddress => { - sort_order => 110, - selection_type => 0, - - labels => [ 'Enter multiple IP addresses', # loc - 'Enter one IP address', # loc - 'Enter up to [_1] IP addresses', # loc - ] - }, - IPAddressRange => { - sort_order => 120, - selection_type => 0, - - labels => [ 'Enter multiple IP address ranges', # loc - 'Enter one IP address range', # loc - 'Enter up to [_1] IP address ranges', # loc - ] - }, -); - - -our %FRIENDLY_OBJECT_TYPES = (); - -RT::CustomField->_ForObjectType( 'RT::Queue-RT::Ticket' => "Tickets", ); #loc -RT::CustomField->_ForObjectType( - 'RT::Queue-RT::Ticket-RT::Transaction' => "Ticket Transactions", ); #loc -RT::CustomField->_ForObjectType( 'RT::User' => "Users", ); #loc -RT::CustomField->_ForObjectType( 'RT::Queue' => "Queues", ); #loc -RT::CustomField->_ForObjectType( 'RT::Group' => "Groups", ); #loc - -our $RIGHTS = { - SeeCustomField => 'View custom fields', # loc_pair - AdminCustomField => 'Create, modify and delete custom fields', # loc_pair - AdminCustomFieldValues => 'Create, modify and delete custom fields values', # loc_pair - ModifyCustomField => 'Add, modify and delete custom field values for objects' # loc_pair -}; - -our $RIGHT_CATEGORIES = { - SeeCustomField => 'General', - AdminCustomField => 'Admin', - AdminCustomFieldValues => 'Admin', - ModifyCustomField => 'Staff', -}; - -# Tell RT::ACE that this sort of object can get acls granted -$RT::ACE::OBJECT_TYPES{'RT::CustomField'} = 1; - -__PACKAGE__->AddRights(%$RIGHTS); -__PACKAGE__->AddRightCategories(%$RIGHT_CATEGORIES); - -=head2 AddRights C<RIGHT>, C<DESCRIPTION> [, ...] - -Adds the given rights to the list of possible rights. This method -should be called during server startup, not at runtime. - -=cut - -sub AddRights { - my $self = shift; - my %new = @_; - $RIGHTS = { %$RIGHTS, %new }; - %RT::ACE::LOWERCASERIGHTNAMES = ( %RT::ACE::LOWERCASERIGHTNAMES, - map { lc($_) => $_ } keys %new); -} - -sub AvailableRights { - my $self = shift; - return $RIGHTS; -} - -=head2 RightCategories - -Returns a hashref where the keys are rights for this type of object and the -values are the category (General, Staff, Admin) the right falls into. - -=cut - -sub RightCategories { - return $RIGHT_CATEGORIES; -} - -=head2 AddRightCategories C<RIGHT>, C<CATEGORY> [, ...] - -Adds the given right and category pairs to the list of right categories. This -method should be called during server startup, not at runtime. - -=cut - -sub AddRightCategories { - my $self = shift if ref $_[0] or $_[0] eq __PACKAGE__; - my %new = @_; - $RIGHT_CATEGORIES = { %$RIGHT_CATEGORIES, %new }; -} - -=head1 NAME - - RT::CustomField_Overlay - overlay for RT::CustomField - -=head1 DESCRIPTION - -=head1 'CORE' METHODS - -=head2 Create PARAMHASH - -Create takes a hash of values and creates a row in the database: - - varchar(200) 'Name'. - varchar(200) 'Type'. - int(11) 'MaxValues'. - varchar(255) 'Pattern'. - smallint(6) 'Repeated'. - varchar(255) 'Description'. - int(11) 'SortOrder'. - varchar(255) 'LookupType'. - smallint(6) 'Disabled'. - -C<LookupType> is generally the result of either -C<RT::Ticket->CustomFieldLookupType> or C<RT::Transaction->CustomFieldLookupType>. - -=cut - -sub Create { - my $self = shift; - my %args = ( - Name => '', - Type => '', - MaxValues => 0, - Pattern => '', - Description => '', - Disabled => 0, - LookupType => '', - Repeated => 0, - LinkValueTo => '', - IncludeContentForValue => '', - @_, - ); - - unless ( $self->CurrentUser->HasRight(Object => $RT::System, Right => 'AdminCustomField') ) { - return (0, $self->loc('Permission Denied')); - } - - if ( $args{TypeComposite} ) { - @args{'Type', 'MaxValues'} = split(/-/, $args{TypeComposite}, 2); - } - elsif ( $args{Type} =~ s/(?:(Single)|Multiple)$// ) { - # old style Type string - $args{'MaxValues'} = $1 ? 1 : 0; - } - $args{'MaxValues'} = int $args{'MaxValues'}; - - if ( !exists $args{'Queue'}) { - # do nothing -- things below are strictly backward compat - } - elsif ( ! $args{'Queue'} ) { - unless ( $self->CurrentUser->HasRight( Object => $RT::System, Right => 'AssignCustomFields') ) { - return ( 0, $self->loc('Permission Denied') ); - } - $args{'LookupType'} = 'RT::Queue-RT::Ticket'; - } - else { - my $queue = RT::Queue->new($self->CurrentUser); - $queue->Load($args{'Queue'}); - unless ($queue->Id) { - return (0, $self->loc("Queue not found")); - } - unless ( $queue->CurrentUserHasRight('AssignCustomFields') ) { - return ( 0, $self->loc('Permission Denied') ); - } - $args{'LookupType'} = 'RT::Queue-RT::Ticket'; - $args{'Queue'} = $queue->Id; - } - - my ($ok, $msg) = $self->_IsValidRegex( $args{'Pattern'} ); - return (0, $self->loc("Invalid pattern: [_1]", $msg)) unless $ok; - - if ( $args{'MaxValues'} != 1 && $args{'Type'} =~ /(text|combobox)$/i ) { - $RT::Logger->debug("Support for 'multiple' Texts or Comboboxes is not implemented"); - $args{'MaxValues'} = 1; - } - - if ( $args{'RenderType'} ||= undef ) { - my $composite = join '-', @args{'Type', 'MaxValues'}; - return (0, $self->loc("This custom field has no Render Types")) - unless $self->HasRenderTypes( $composite ); - - if ( $args{'RenderType'} eq $self->DefaultRenderType( $composite ) ) { - $args{'RenderType'} = undef; - } else { - return (0, $self->loc("Invalid Render Type") ) - unless grep $_ eq $args{'RenderType'}, $self->RenderTypes( $composite ); - } - } - - $args{'ValuesClass'} = undef if ($args{'ValuesClass'} || '') eq 'RT::CustomFieldValues'; - if ( $args{'ValuesClass'} ||= undef ) { - return (0, $self->loc("This Custom Field can not have list of values")) - unless $self->IsSelectionType( $args{'Type'} ); - - unless ( $self->ValidateValuesClass( $args{'ValuesClass'} ) ) { - return (0, $self->loc("Invalid Custom Field values source")); - } - } - - (my $rv, $msg) = $self->SUPER::Create( - Name => $args{'Name'}, - Type => $args{'Type'}, - RenderType => $args{'RenderType'}, - MaxValues => $args{'MaxValues'}, - Pattern => $args{'Pattern'}, - BasedOn => $args{'BasedOn'}, - ValuesClass => $args{'ValuesClass'}, - Description => $args{'Description'}, - Disabled => $args{'Disabled'}, - LookupType => $args{'LookupType'}, - Repeated => $args{'Repeated'}, - ); - - if ($rv) { - if ( exists $args{'LinkValueTo'}) { - $self->SetLinkValueTo($args{'LinkValueTo'}); - } - - if ( exists $args{'IncludeContentForValue'}) { - $self->SetIncludeContentForValue($args{'IncludeContentForValue'}); - } - - if ( exists $args{'UILocation'} ) { - $self->SetUILocation( $args{'UILocation'} ); - } - - if ( exists $args{'NoClone'} ) { - $self->SetNoClone( $args{'NoClone'} ); - } - - return ($rv, $msg) unless exists $args{'Queue'}; - - # Compat code -- create a new ObjectCustomField mapping - my $OCF = RT::ObjectCustomField->new( $self->CurrentUser ); - $OCF->Create( - CustomField => $self->Id, - ObjectId => $args{'Queue'}, - ); - } - - return ($rv, $msg); -} - -=head2 Load ID/NAME - -Load a custom field. If the value handed in is an integer, load by custom field ID. Otherwise, Load by name. - -=cut - -sub Load { - my $self = shift; - my $id = shift || ''; - - if ( $id =~ /^\d+$/ ) { - return $self->SUPER::Load( $id ); - } else { - return $self->LoadByName( Name => $id ); - } -} - - - -=head2 LoadByName (Queue => QUEUEID, Name => NAME) - -Loads the Custom field named NAME. - -Will load a Disabled Custom Field even if there is a non-disabled Custom Field -with the same Name. - -If a Queue parameter is specified, only look for ticket custom fields tied to that Queue. - -If the Queue parameter is '0', look for global ticket custom fields. - -If no queue parameter is specified, look for any and all custom fields with this name. - -BUG/TODO, this won't let you specify that you only want user or group CFs. - -=cut - -# Compatibility for API change after 3.0 beta 1 -*LoadNameAndQueue = \&LoadByName; -# Change after 3.4 beta. -*LoadByNameAndQueue = \&LoadByName; - -sub LoadByName { - my $self = shift; - my %args = ( - Queue => undef, - Name => undef, - @_, - ); - - unless ( defined $args{'Name'} && length $args{'Name'} ) { - $RT::Logger->error("Couldn't load Custom Field without Name"); - return wantarray ? (0, $self->loc("No name provided")) : 0; - } - - # if we're looking for a queue by name, make it a number - 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 - - my $CFs = RT::CustomFields->new( $self->CurrentUser ); - $CFs->SetContextObject( $self->ContextObject ); - my $field = $args{'Name'} =~ /\D/? 'Name' : 'id'; - $CFs->Limit( FIELD => $field, VALUE => $args{'Name'}, CASESENSITIVE => 0); - # Don't limit to queue if queue is 0. Trying to do so breaks - # RT::Group type CFs. - if ( defined $args{'Queue'} ) { - $CFs->LimitToQueue( $args{'Queue'} ); - } - - # When loading by name, we _can_ load disabled fields, but prefer - # non-disabled fields. - $CFs->FindAllRows; - $CFs->OrderByCols( - { FIELD => "Disabled", ORDER => 'ASC' }, - ); - - # We only want one entry. - $CFs->RowsPerPage(1); - - # version before 3.8 just returns 0, so we need to test if wantarray to be - # backward compatible. - return wantarray ? (0, $self->loc("Not found")) : 0 unless my $first = $CFs->First; - - return $self->LoadById( $first->id ); -} - - - - -=head2 Custom field values - -=head3 Values FIELD - -Return a object (collection) of all acceptable values for this Custom Field. -Class of the object can vary and depends on the return value -of the C<ValuesClass> method. - -=cut - -*ValuesObj = \&Values; - -sub Values { - my $self = shift; - - my $class = $self->ValuesClass; - if ( $class ne 'RT::CustomFieldValues') { - eval "require $class" or die "$@"; - } - my $cf_values = $class->new( $self->CurrentUser ); - # 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); -} - - -=head3 AddValue HASH - -Create a new value for this CustomField. Takes a paramhash containing the elements Name, Description and SortOrder - -=cut - -sub AddValue { - my $self = shift; - my %args = @_; - - unless ($self->CurrentUserHasRight('AdminCustomField') || $self->CurrentUserHasRight('AdminCustomFieldValues')) { - return (0, $self->loc('Permission Denied')); - } - - # allow zero value - if ( !defined $args{'Name'} || $args{'Name'} eq '' ) { - return (0, $self->loc("Can't add a custom field value without a name")); - } - - my $newval = RT::CustomFieldValue->new( $self->CurrentUser ); - return $newval->Create( %args, CustomField => $self->Id ); -} - - - - -=head3 DeleteValue ID - -Deletes a value from this custom field by id. - -Does not remove this value for any article which has had it selected - -=cut - -sub DeleteValue { - my $self = shift; - my $id = shift; - unless ( $self->CurrentUserHasRight('AdminCustomField') || $self->CurrentUserHasRight('AdminCustomFieldValues') ) { - return (0, $self->loc('Permission Denied')); - } - - my $val_to_del = RT::CustomFieldValue->new( $self->CurrentUser ); - $val_to_del->Load( $id ); - unless ( $val_to_del->Id ) { - return (0, $self->loc("Couldn't find that value")); - } - unless ( $val_to_del->CustomField == $self->Id ) { - return (0, $self->loc("That is not a value for this custom field")); - } - - my $retval = $val_to_del->Delete; - unless ( $retval ) { - return (0, $self->loc("Custom field value could not be deleted")); - } - return ($retval, $self->loc("Custom field value deleted")); -} - - -=head2 ValidateQueue Queue - -Make sure that the name specified is valid - -=cut - -sub ValidateName { - my $self = shift; - my $value = shift; - - return 0 unless length $value; - - return $self->SUPER::ValidateName($value); -} - -=head2 ValidateQueue Queue - -Make sure that the queue specified is a valid queue name - -=cut - -sub ValidateQueue { - my $self = shift; - my $id = shift; - - return undef unless defined $id; - # 0 means "Global" null would _not_ be ok. - return 1 if $id eq '0'; - - my $q = RT::Queue->new( RT->SystemUser ); - $q->Load( $id ); - return undef unless $q->id; - return 1; -} - - - -=head2 Types - -Retuns an array of the types of CustomField that are supported - -=cut - -sub Types { - return (sort {(($FieldTypes{$a}{sort_order}||999) <=> ($FieldTypes{$b}{sort_order}||999)) or ($a cmp $b)} keys %FieldTypes); -} - - -=head2 IsSelectionType - -Retuns a boolean value indicating whether the C<Values> method makes sense -to this Custom Field. - -=cut - -sub IsSelectionType { - my $self = shift; - my $type = @_? shift : $self->Type; - return undef unless $type; - return $FieldTypes{$type}->{selection_type}; -} - - - -=head2 IsExternalValues - -=cut - -sub IsExternalValues { - my $self = shift; - return 0 unless $self->IsSelectionType( @_ ); - return $self->ValuesClass eq 'RT::CustomFieldValues'? 0 : 1; -} - -sub ValuesClass { - my $self = shift; - return $self->_Value( ValuesClass => @_ ) || 'RT::CustomFieldValues'; -} - -sub SetValuesClass { - my $self = shift; - my $class = shift || 'RT::CustomFieldValues'; - - if ( $class eq 'RT::CustomFieldValues' ) { - return $self->_Set( Field => 'ValuesClass', Value => undef, @_ ); - } - - return (0, $self->loc("This Custom Field can not have list of values")) - unless $self->IsSelectionType; - - unless ( $self->ValidateValuesClass( $class ) ) { - return (0, $self->loc("Invalid Custom Field values source")); - } - return $self->_Set( Field => 'ValuesClass', Value => $class, @_ ); -} - -sub ValidateValuesClass { - my $self = shift; - my $class = shift; - - return 1 if !$class || $class eq 'RT::CustomFieldValues'; - return 1 if grep $class eq $_, RT->Config->Get('CustomFieldValuesSources'); - return undef; -} - - -=head2 FriendlyType [TYPE, MAX_VALUES] - -Returns a localized human-readable version of the custom field type. -If a custom field type is specified as the parameter, the friendly type for that type will be returned - -=cut - -sub FriendlyType { - my $self = shift; - - my $type = @_ ? shift : $self->Type; - my $max = @_ ? shift : $self->MaxValues; - $max = 0 unless $max; - - if (my $friendly_type = $FieldTypes{$type}->{labels}->[$max>2 ? 2 : $max]) { - return ( $self->loc( $friendly_type, $max ) ); - } - else { - return ( $self->loc( $type ) ); - } -} - -sub FriendlyTypeComposite { - my $self = shift; - my $composite = shift || $self->TypeComposite; - return $self->FriendlyType(split(/-/, $composite, 2)); -} - - -=head2 ValidateType TYPE - -Takes a single string. returns true if that string is a value -type of custom field - - -=cut - -sub ValidateType { - my $self = shift; - my $type = shift; - - if ( $type =~ s/(?:Single|Multiple)$// ) { - $RT::Logger->warning( "Prefix 'Single' and 'Multiple' to Type deprecated, use MaxValues instead at (". join(":",caller).")"); - } - - if ( $FieldTypes{$type} ) { - return 1; - } - else { - return undef; - } -} - - -sub SetType { - my $self = shift; - my $type = shift; - if ($type =~ s/(?:(Single)|Multiple)$//) { - $RT::Logger->warning("'Single' and 'Multiple' on SetType deprecated, use SetMaxValues instead at (". join(":",caller).")"); - $self->SetMaxValues($1 ? 1 : 0); - } - $self->_Set(Field => 'Type', Value =>$type); -} - -=head2 SetPattern STRING - -Takes a single string representing a regular expression. Performs basic -validation on that regex, and sets the C<Pattern> field for the CF if it -is valid. - -=cut - -sub SetPattern { - my $self = shift; - my $regex = shift; - - my ($ok, $msg) = $self->_IsValidRegex($regex); - if ($ok) { - return $self->_Set(Field => 'Pattern', Value => $regex); - } - else { - return (0, $self->loc("Invalid pattern: [_1]", $msg)); - } -} - -=head2 _IsValidRegex(Str $regex) returns (Bool $success, Str $msg) - -Tests if the string contains an invalid regex. - -=cut - -sub _IsValidRegex { - my $self = shift; - my $regex = shift or return (1, 'valid'); - - local $^W; local $@; - local $SIG{__DIE__} = sub { 1 }; - local $SIG{__WARN__} = sub { 1 }; - - if (eval { qr/$regex/; 1 }) { - return (1, 'valid'); - } - - my $err = $@; - $err =~ s{[,;].*}{}; # strip debug info from error - chomp $err; - return (0, $err); -} - - -=head2 SingleValue - -Returns true if this CustomField only accepts a single value. -Returns false if it accepts multiple values - -=cut - -sub SingleValue { - my $self = shift; - if (($self->MaxValues||0) == 1) { - return 1; - } - else { - return undef; - } -} - -sub UnlimitedValues { - my $self = shift; - if (($self->MaxValues||0) == 0) { - return 1; - } - else { - return undef; - } -} - - -=head2 CurrentUserHasRight RIGHT - -Helper function to call the custom field's queue's CurrentUserHasRight with the passed in args. - -=cut - -sub CurrentUserHasRight { - my $self = shift; - my $right = shift; - - return $self->CurrentUser->HasRight( - Object => $self, - Right => $right, - ); -} - -=head2 ACLEquivalenceObjects - -Returns list of objects via which users can get rights on this custom field. For custom fields -these objects can be set using L<ContextObject|/"ContextObject and SetContextObject">. - -=cut - -sub ACLEquivalenceObjects { - my $self = shift; - - my $ctx = $self->ContextObject - or return; - return ($ctx, $ctx->ACLEquivalenceObjects); -} - -=head2 ContextObject and SetContextObject - -Set or get a context for this object. It can be ticket, queue or another object -this CF applies to. Used for ACL control, for example SeeCustomField can be granted on -queue level to allow people to see all fields applied to the queue. - -=cut - -sub SetContextObject { - my $self = shift; - return $self->{'context_object'} = shift; -} - -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 { - my $self = shift; - - unless ( $self->CurrentUserHasRight('AdminCustomField') ) { - return ( 0, $self->loc('Permission Denied') ); - } - return $self->SUPER::_Set( @_ ); - -} - - - -=head2 _Value - -Takes the name of a table column. -Returns its value as a string, if the user passes an ACL check - -=cut - -sub _Value { - my $self = shift; - return undef unless $self->id; - - # we need to do the rights check - unless ( $self->CurrentUserHasRight('SeeCustomField') ) { - $RT::Logger->debug( - "Permission denied. User #". $self->CurrentUser->id - ." has no SeeCustomField right on CF #". $self->id - ); - return (undef); - } - return $self->__Value( @_ ); -} - - -=head2 SetDisabled - -Takes a boolean. -1 will cause this custom field to no longer be avaialble for objects. -0 will re-enable this field. - -=cut - - -=head2 SetTypeComposite - -Set this custom field's type and maximum values as a composite value - -=cut - -sub SetTypeComposite { - my $self = shift; - my $composite = shift; - - my $old = $self->TypeComposite; - - my ($type, $max_values) = split(/-/, $composite, 2); - if ( $type ne $self->Type ) { - my ($status, $msg) = $self->SetType( $type ); - return ($status, $msg) unless $status; - } - if ( ($max_values || 0) != ($self->MaxValues || 0) ) { - my ($status, $msg) = $self->SetMaxValues( $max_values ); - return ($status, $msg) unless $status; - } - my $render = $self->RenderType; - if ( $render and not grep { $_ eq $render } $self->RenderTypes ) { - # We switched types and our render type is no longer valid, so unset it - # and use the default - $self->SetRenderType( undef ); - } - return 1, $self->loc( - "Type changed from '[_1]' to '[_2]'", - $self->FriendlyTypeComposite( $old ), - $self->FriendlyTypeComposite( $composite ), - ); -} - -=head2 TypeComposite - -Returns a composite value composed of this object's type and maximum values - -=cut - - -sub TypeComposite { - my $self = shift; - return join '-', ($self->Type || ''), ($self->MaxValues || 0); -} - -=head2 TypeComposites - -Returns an array of all possible composite values for custom fields. - -=cut - -sub TypeComposites { - my $self = shift; - return grep !/(?:[Tt]ext|Combobox|Date|DateTime|TimeValue)-0/, map { ("$_-1", "$_-0") } $self->Types; -} - -=head2 RenderType - -Returns the type of form widget to render for this custom field. Currently -this only affects fields which return true for L</HasRenderTypes>. - -=cut - -sub RenderType { - my $self = shift; - return '' unless $self->HasRenderTypes; - - return $self->_Value( 'RenderType', @_ ) - || $self->DefaultRenderType; -} - -=head2 SetRenderType TYPE - -Sets this custom field's render type. - -=cut - -sub SetRenderType { - my $self = shift; - my $type = shift; - return (0, $self->loc("This custom field has no Render Types")) - unless $self->HasRenderTypes; - - if ( !$type || $type eq $self->DefaultRenderType ) { - return $self->_Set( Field => 'RenderType', Value => undef, @_ ); - } - - if ( not grep { $_ eq $type } $self->RenderTypes ) { - return (0, $self->loc("Invalid Render Type for custom field of type [_1]", - $self->FriendlyType)); - } - - return $self->_Set( Field => 'RenderType', Value => $type, @_ ); -} - -=head2 DefaultRenderType [TYPE COMPOSITE] - -Returns the default render type for this custom field's type or the TYPE -COMPOSITE specified as an argument. - -=cut - -sub DefaultRenderType { - my $self = shift; - my $composite = @_ ? shift : $self->TypeComposite; - my ($type, $max) = split /-/, $composite, 2; - return unless $type and $self->HasRenderTypes($composite); - return $FieldTypes{$type}->{render_types}->{ $max == 1 ? 'single' : 'multiple' }[0]; -} - -=head2 HasRenderTypes [TYPE_COMPOSITE] - -Returns a boolean value indicating whether the L</RenderTypes> and -L</RenderType> methods make sense for this custom field. - -Currently true only for type C<Select>. - -=cut - -sub HasRenderTypes { - my $self = shift; - my ($type, $max) = split /-/, (@_ ? shift : $self->TypeComposite), 2; - return undef unless $type; - return defined $FieldTypes{$type}->{render_types} - ->{ $max == 1 ? 'single' : 'multiple' }; -} - -=head2 RenderTypes [TYPE COMPOSITE] - -Returns the valid render types for this custom field's type or the TYPE -COMPOSITE specified as an argument. - -=cut - -sub RenderTypes { - my $self = shift; - my $composite = @_ ? shift : $self->TypeComposite; - my ($type, $max) = split /-/, $composite, 2; - return unless $type and $self->HasRenderTypes($composite); - return @{$FieldTypes{$type}->{render_types}->{ $max == 1 ? 'single' : 'multiple' }}; -} - -=head2 SetLookupType - -Autrijus: care to doc how LookupTypes work? - -=cut - -sub SetLookupType { - my $self = shift; - my $lookup = shift; - if ( $lookup ne $self->LookupType ) { - # Okay... We need to invalidate our existing relationships - my $ObjectCustomFields = RT::ObjectCustomFields->new($self->CurrentUser); - $ObjectCustomFields->LimitToCustomField($self->Id); - $_->Delete foreach @{$ObjectCustomFields->ItemsArrayRef}; - } - return $self->_Set(Field => 'LookupType', Value =>$lookup); -} - -=head2 LookupTypes - -Returns an array of LookupTypes available - -=cut - - -sub LookupTypes { - my $self = shift; - return sort keys %FRIENDLY_OBJECT_TYPES; -} - -my @FriendlyObjectTypes = ( - "[_1] objects", # loc - "[_1]'s [_2] objects", # loc - "[_1]'s [_2]'s [_3] objects", # loc -); - -=head2 FriendlyLookupType - -Returns a localized description of the type of this custom field - -=cut - -sub FriendlyLookupType { - my $self = shift; - my $lookup = shift || $self->LookupType; - - return ($self->loc( $FRIENDLY_OBJECT_TYPES{$lookup} )) - if (defined $FRIENDLY_OBJECT_TYPES{$lookup} ); - - my @types = map { s/^RT::// ? $self->loc($_) : $_ } - grep { defined and length } - split( /-/, $lookup ) - or return; - return ( $self->loc( $FriendlyObjectTypes[$#types], @types ) ); -} - -=head1 RecordClassFromLookupType - -Returns the type of Object referred to by ObjectCustomFields' ObjectId column - -Optionally takes a LookupType to use instead of using the value on the loaded -record. In this case, the method may be called on the class instead of an -object. - -=cut - -sub RecordClassFromLookupType { - my $self = shift; - my $type = shift || $self->LookupType; - my ($class) = ($type =~ /^([^-]+)/); - unless ( $class ) { - if (blessed($self) and $self->LookupType eq $type) { - $RT::Logger->error( - "Custom Field #". $self->id - ." has incorrect LookupType '$type'" - ); - } else { - RT->Logger->error("Invalid LookupType passed as argument: $type"); - } - return undef; - } - return $class; -} - -=head1 ObjectTypeFromLookupType - -Returns the ObjectType used in ObjectCustomFieldValues rows for this CF - -Optionally takes a LookupType to use instead of using the value on the loaded -record. In this case, the method may be called on the class instead of an -object. - -=cut - -sub ObjectTypeFromLookupType { - my $self = shift; - my $type = shift || $self->LookupType; - my ($class) = ($type =~ /([^-]+)$/); - unless ( $class ) { - if (blessed($self) and $self->LookupType eq $type) { - $RT::Logger->error( - "Custom Field #". $self->id - ." has incorrect LookupType '$type'" - ); - } else { - RT->Logger->error("Invalid LookupType passed as argument: $type"); - } - return undef; - } - return $class; -} - -sub CollectionClassFromLookupType { - my $self = shift; - - my $record_class = $self->RecordClassFromLookupType; - return undef unless $record_class; - - my $collection_class; - if ( UNIVERSAL::can($record_class.'Collection', 'new') ) { - $collection_class = $record_class.'Collection'; - } elsif ( UNIVERSAL::can($record_class.'es', 'new') ) { - $collection_class = $record_class.'es'; - } elsif ( UNIVERSAL::can($record_class.'s', 'new') ) { - $collection_class = $record_class.'s'; - } else { - $RT::Logger->error("Can not find a collection class for record class '$record_class'"); - return undef; - } - return $collection_class; -} - -=head1 ApplyGlobally - -Certain custom fields (users, groups) should only be applied globally -but rather than regexing in code for LookupType =~ RT::Queue, we'll codify -the rules here. - -=cut - -sub ApplyGlobally { - my $self = shift; - - return ($self->LookupType =~ /^RT::(?:Group|User)/io); - -} - -=head1 AppliedTo - -Returns collection with objects this custom field is applied to. -Class of the collection depends on L</LookupType>. -See all L</NotAppliedTo> . - -Doesn't takes into account if object is applied globally. - -=cut - -sub AppliedTo { - my $self = shift; - - my ($res, $ocfs_alias) = $self->_AppliedTo; - return $res unless $res; - - $res->Limit( - ALIAS => $ocfs_alias, - FIELD => 'id', - OPERATOR => 'IS NOT', - VALUE => 'NULL', - ); - - return $res; -} - -=head1 NotAppliedTo - -Returns collection with objects this custom field is not applied to. -Class of the collection depends on L</LookupType>. -See all L</AppliedTo> . - -Doesn't takes into account if object is applied globally. - -=cut - -sub NotAppliedTo { - my $self = shift; - - my ($res, $ocfs_alias) = $self->_AppliedTo; - return $res unless $res; - - $res->Limit( - ALIAS => $ocfs_alias, - FIELD => 'id', - OPERATOR => 'IS', - VALUE => 'NULL', - ); - - return $res; -} - -sub _AppliedTo { - my $self = shift; - - my ($class) = $self->CollectionClassFromLookupType; - return undef unless $class; - - my $res = $class->new( $self->CurrentUser ); - - # If CF is a Group CF, only display user-defined groups - if ( $class eq 'RT::Groups' ) { - $res->LimitToUserDefinedGroups; - } - - $res->OrderBy( FIELD => 'Name' ); - my $ocfs_alias = $res->Join( - TYPE => 'LEFT', - ALIAS1 => 'main', - FIELD1 => 'id', - TABLE2 => 'ObjectCustomFields', - FIELD2 => 'ObjectId', - ); - $res->Limit( - LEFTJOIN => $ocfs_alias, - ALIAS => $ocfs_alias, - FIELD => 'CustomField', - VALUE => $self->id, - ); - return ($res, $ocfs_alias); -} - -=head2 IsApplied - -Takes object id and returns corresponding L<RT::ObjectCustomField> -record if this custom field is applied to the object. Use 0 to check -if custom field is applied globally. - -=cut - -sub IsApplied { - my $self = shift; - my $id = shift; - my $ocf = RT::ObjectCustomField->new( $self->CurrentUser ); - $ocf->LoadByCols( CustomField => $self->id, ObjectId => $id || 0 ); - return undef unless $ocf->id; - return $ocf; -} - -=head2 AddToObject OBJECT - -Add this custom field as a custom field for a single object, such as a queue or group. - -Takes an object - -=cut - - -sub AddToObject { - my $self = shift; - my $object = shift; - my $id = $object->Id || 0; - - unless (index($self->LookupType, ref($object)) == 0) { - return ( 0, $self->loc('Lookup type mismatch') ); - } - - unless ( $object->CurrentUserHasRight('AssignCustomFields') ) { - return ( 0, $self->loc('Permission Denied') ); - } - - if ( $self->IsApplied( $id ) ) { - return ( 0, $self->loc("Custom field is already applied to the object") ); - } - - if ( $id ) { - # applying locally - return (0, $self->loc("Couldn't apply custom field to an object as it's global already") ) - if $self->IsApplied( 0 ); - } - else { - my $applied = RT::ObjectCustomFields->new( $self->CurrentUser ); - $applied->LimitToCustomField( $self->id ); - while ( my $record = $applied->Next ) { - $record->Delete; - } - } - - my $ocf = RT::ObjectCustomField->new( $self->CurrentUser ); - my ( $oid, $msg ) = $ocf->Create( - ObjectId => $id, CustomField => $self->id, - ); - return ( $oid, $msg ); -} - - -=head2 RemoveFromObject OBJECT - -Remove this custom field for a single object, such as a queue or group. - -Takes an object - -=cut - -sub RemoveFromObject { - my $self = shift; - my $object = shift; - my $id = $object->Id || 0; - - unless (index($self->LookupType, ref($object)) == 0) { - return ( 0, $self->loc('Object type mismatch') ); - } - - unless ( $object->CurrentUserHasRight('AssignCustomFields') ) { - return ( 0, $self->loc('Permission Denied') ); - } - - my $ocf = $self->IsApplied( $id ); - unless ( $ocf ) { - return ( 0, $self->loc("This custom field does not apply to that object") ); - } - - # XXX: Delete doesn't return anything - my ( $oid, $msg ) = $ocf->Delete; - return ( $oid, $msg ); -} - - -=head2 AddValueForObject HASH - -Adds a custom field value for a record object of some kind. -Takes a param hash of - -Required: - - Object - Content - -Optional: - - LargeContent - ContentType - -=cut - -sub AddValueForObject { - my $self = shift; - my %args = ( - Object => undef, - Content => undef, - LargeContent => undef, - ContentType => undef, - @_ - ); - my $obj = $args{'Object'} or return ( 0, $self->loc('Invalid object') ); - - unless ( $self->CurrentUserHasRight('ModifyCustomField') ) { - return ( 0, $self->loc('Permission Denied') ); - } - - unless ( $self->MatchPattern($args{'Content'}) ) { - return ( 0, $self->loc('Input must match [_1]', $self->FriendlyPattern) ); - } - - $RT::Handle->BeginTransaction; - - if ( $self->MaxValues ) { - my $current_values = $self->ValuesForObject($obj); - my $extra_values = ( $current_values->Count + 1 ) - $self->MaxValues; - - # (The +1 is for the new value we're adding) - - # If we have a set of current values and we've gone over the maximum - # allowed number of values, we'll need to delete some to make room. - # which former values are blown away is not guaranteed - - while ($extra_values) { - my $extra_item = $current_values->Next; - unless ( $extra_item->id ) { - $RT::Logger->crit( "We were just asked to delete " - ."a custom field value that doesn't exist!" ); - $RT::Handle->Rollback(); - return (undef); - } - $extra_item->Delete; - $extra_values--; - } - } - - if (my $canonicalizer = $self->can('_CanonicalizeValue'.$self->Type)) { - $canonicalizer->($self, \%args); - } - - - - my $newval = RT::ObjectCustomFieldValue->new( $self->CurrentUser ); - my ($val, $msg) = $newval->Create( - ObjectType => ref($obj), - ObjectId => $obj->Id, - Content => $args{'Content'}, - LargeContent => $args{'LargeContent'}, - ContentType => $args{'ContentType'}, - CustomField => $self->Id - ); - - unless ($val) { - $RT::Handle->Rollback(); - return ($val, $self->loc("Couldn't create record: [_1]", $msg)); - } - - $RT::Handle->Commit(); - return ($val); - -} - - - -sub _CanonicalizeValueDateTime { - my $self = shift; - my $args = shift; - my $DateObj = RT::Date->new( $self->CurrentUser ); - $DateObj->Set( Format => 'unknown', - Value => $args->{'Content'} ); - $args->{'Content'} = $DateObj->ISO; -} - -# For date, we need to store Content as ISO date -sub _CanonicalizeValueDate { - my $self = shift; - my $args = shift; - - # in case user input date with time, let's omit it by setting timezone - # to utc so "hour" won't affect "day" - my $DateObj = RT::Date->new( $self->CurrentUser ); - $DateObj->Set( Format => 'unknown', - Value => $args->{'Content'}, - ); - $args->{'Content'} = $DateObj->Date( Timezone => 'user' ); -} - -=head2 MatchPattern STRING - -Tests the incoming string against the Pattern of this custom field object -and returns a boolean; returns true if the Pattern is empty. - -=cut - -sub MatchPattern { - my $self = shift; - my $regex = $self->Pattern or return 1; - - return (( defined $_[0] ? $_[0] : '') =~ $regex); -} - - - - -=head2 FriendlyPattern - -Prettify the pattern of this custom field, by taking the text in C<(?#text)> -and localizing it. - -=cut - -sub FriendlyPattern { - my $self = shift; - my $regex = $self->Pattern; - - return '' unless length $regex; - if ( $regex =~ /\(\?#([^)]*)\)/ ) { - return '[' . $self->loc($1) . ']'; - } - else { - return $regex; - } -} - - - - -=head2 DeleteValueForObject HASH - -Deletes a custom field value for a ticket. Takes a param hash of Object and Content - -Returns a tuple of (STATUS, MESSAGE). If the call succeeded, the STATUS is true. otherwise it's false - -=cut - -sub DeleteValueForObject { - my $self = shift; - my %args = ( Object => undef, - Content => undef, - Id => undef, - @_ ); - - - unless ($self->CurrentUserHasRight('ModifyCustomField')) { - return (0, $self->loc('Permission Denied')); - } - - my $oldval = RT::ObjectCustomFieldValue->new($self->CurrentUser); - - if (my $id = $args{'Id'}) { - $oldval->Load($id); - } - unless ($oldval->id) { - $oldval->LoadByObjectContentAndCustomField( - Object => $args{'Object'}, - Content => $args{'Content'}, - CustomField => $self->Id, - ); - } - - - # check to make sure we found it - unless ($oldval->Id) { - return(0, $self->loc("Custom field value [_1] could not be found for custom field [_2]", $args{'Content'}, $self->Name)); - } - - # for single-value fields, we need to validate that empty string is a valid value for it - if ( $self->SingleValue and not $self->MatchPattern( '' ) ) { - return ( 0, $self->loc('Input must match [_1]', $self->FriendlyPattern) ); - } - - # delete it - - my $ret = $oldval->Delete(); - unless ($ret) { - return(0, $self->loc("Custom field value could not be found")); - } - return($oldval->Id, $self->loc("Custom field value deleted")); -} - - -=head2 ValuesForObject OBJECT - -Return an L<RT::ObjectCustomFieldValues> object containing all of this custom field's values for OBJECT - -=cut - -sub ValuesForObject { - my $self = shift; - my $object = shift; - - my $values = RT::ObjectCustomFieldValues->new($self->CurrentUser); - unless ($self->id and $self->CurrentUserHasRight('SeeCustomField')) { - # Return an empty object if they have no rights to see - $values->Limit( FIELD => "id", VALUE => 0, SUBCLAUSE => "ACL" ); - return ($values); - } - - $values->LimitToCustomField($self->Id); - $values->LimitToObject($object); - - return ($values); -} - - -=head2 _ForObjectType PATH FRIENDLYNAME - -Tell RT that a certain object accepts custom fields - -Examples: - - 'RT::Queue-RT::Ticket' => "Tickets", # loc - 'RT::Queue-RT::Ticket-RT::Transaction' => "Ticket Transactions", # loc - 'RT::User' => "Users", # loc - 'RT::Group' => "Groups", # loc - 'RT::Queue' => "Queues", # loc - -This is a class method. - -=cut - -sub _ForObjectType { - my $self = shift; - my $path = shift; - my $friendly_name = shift; - - $FRIENDLY_OBJECT_TYPES{$path} = $friendly_name; - -} - - -=head2 IncludeContentForValue [VALUE] (and SetIncludeContentForValue) - -Gets or sets the C<IncludeContentForValue> for this custom field. RT -uses this field to automatically include content into the user's browser -as they display records with custom fields in RT. - -=cut - -sub SetIncludeContentForValue { - shift->IncludeContentForValue(@_); -} -sub IncludeContentForValue{ - my $self = shift; - $self->_URLTemplate('IncludeContentForValue', @_); -} - - - -=head2 LinkValueTo [VALUE] (and SetLinkValueTo) - -Gets or sets the C<LinkValueTo> for this custom field. RT -uses this field to make custom field values into hyperlinks in the user's -browser as they display records with custom fields in RT. - -=cut - - -sub SetLinkValueTo { - shift->LinkValueTo(@_); -} - -sub LinkValueTo { - my $self = shift; - $self->_URLTemplate('LinkValueTo', @_); - -} - - -=head2 _URLTemplate NAME [VALUE] - -With one argument, returns the _URLTemplate named C<NAME>, but only if -the current user has the right to see this custom field. - -With two arguments, attemptes to set the relevant template value. - -=cut - -sub _URLTemplate { - my $self = shift; - my $template_name = shift; - if (@_) { - - my $value = shift; - unless ( $self->CurrentUserHasRight('AdminCustomField') ) { - return ( 0, $self->loc('Permission Denied') ); - } - $self->SetAttribute( Name => $template_name, Content => $value ); - return ( 1, $self->loc('Updated') ); - } else { - unless ( $self->id && $self->CurrentUserHasRight('SeeCustomField') ) { - return (undef); - } - - my @attr = $self->Attributes->Named($template_name); - my $attr = shift @attr; - - if ($attr) { return $attr->Content } - - } -} - -sub SetBasedOn { - my $self = shift; - my $value = shift; - - return $self->_Set( Field => 'BasedOn', Value => $value, @_ ) - 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'); - - # XXX: Remove this restriction once we support lists and cascaded selects - if ( $self->RenderType =~ /List/ ) { - return (0, $self->loc("We can't currently render as a List when basing categories on another custom field. Please use another render type.")); - } - - return $self->_Set( Field => 'BasedOn', Value => $value, @_ ) -} - -sub BasedOnObj { - my $self = shift; - - my $obj = RT::CustomField->new( $self->CurrentUser ); - $obj->SetContextObject( $self->ContextObject ); - if ( $self->BasedOn ) { - $obj->Load( $self->BasedOn ); - } - 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'); - } -} - -sub NoClone { - my $self = shift; - $self->FirstAttribute('NoClone') ? 1 : ''; -} - -sub SetNoClone { - my $self = shift; - my $value = shift; - if ( $value ) { - return $self->SetAttribute( Name => 'NoClone', Content => 1 ); - } else { - return $self->DeleteAttribute('NoClone'); - } -} - - -=head2 id - -Returns the current value of id. -(In the database, id is stored as int(11).) - - -=cut - - -=head2 Name - -Returns the current value of Name. -(In the database, Name is stored as varchar(200).) - - - -=head2 SetName VALUE - - -Set Name to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, Name will be stored as a varchar(200).) - - -=cut - - -=head2 Type - -Returns the current value of Type. -(In the database, Type is stored as varchar(200).) - - - -=head2 SetType VALUE - - -Set Type to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, Type will be stored as a varchar(200).) - - -=cut - - -=head2 RenderType - -Returns the current value of RenderType. -(In the database, RenderType is stored as varchar(64).) - - - -=head2 SetRenderType VALUE - - -Set RenderType to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, RenderType will be stored as a varchar(64).) - - -=cut - - -=head2 MaxValues - -Returns the current value of MaxValues. -(In the database, MaxValues is stored as int(11).) - - - -=head2 SetMaxValues VALUE - - -Set MaxValues to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, MaxValues will be stored as a int(11).) - - -=cut - - -=head2 Pattern - -Returns the current value of Pattern. -(In the database, Pattern is stored as text.) - - - -=head2 SetPattern VALUE - - -Set Pattern to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, Pattern will be stored as a text.) - - -=cut - - -=head2 Repeated - -Returns the current value of Repeated. -(In the database, Repeated is stored as smallint(6).) - - - -=head2 SetRepeated VALUE - - -Set Repeated to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, Repeated will be stored as a smallint(6).) - - -=cut - - -=head2 BasedOn - -Returns the current value of BasedOn. -(In the database, BasedOn is stored as int(11).) - - - -=head2 SetBasedOn VALUE - - -Set BasedOn to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, BasedOn will be stored as a int(11).) - - -=cut - - -=head2 Description - -Returns the current value of Description. -(In the database, Description is stored as varchar(255).) - - - -=head2 SetDescription VALUE - - -Set Description to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, Description will be stored as a varchar(255).) - - -=cut - - -=head2 SortOrder - -Returns the current value of SortOrder. -(In the database, SortOrder is stored as int(11).) - - - -=head2 SetSortOrder VALUE - - -Set SortOrder to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, SortOrder will be stored as a int(11).) - - -=cut - - -=head2 LookupType - -Returns the current value of LookupType. -(In the database, LookupType is stored as varchar(255).) - - - -=head2 SetLookupType VALUE - - -Set LookupType to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, LookupType will be stored as a varchar(255).) - - -=cut - - -=head2 Creator - -Returns the current value of Creator. -(In the database, Creator is stored as int(11).) - - -=cut - - -=head2 Created - -Returns the current value of Created. -(In the database, Created is stored as datetime.) - - -=cut - - -=head2 LastUpdatedBy - -Returns the current value of LastUpdatedBy. -(In the database, LastUpdatedBy is stored as int(11).) - - -=cut - - -=head2 LastUpdated - -Returns the current value of LastUpdated. -(In the database, LastUpdated is stored as datetime.) - - -=cut - - -=head2 Disabled - -Returns the current value of Disabled. -(In the database, Disabled is stored as smallint(6).) - - - -=head2 SetDisabled VALUE - - -Set Disabled to VALUE. -Returns (1, 'Status message') on success and (0, 'Error Message') on failure. -(In the database, Disabled will be stored as a smallint(6).) - - -=cut - - - -sub _CoreAccessible { - { - - id => - {read => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''}, - Name => - {read => 1, write => 1, sql_type => 12, length => 200, is_blob => 0, is_numeric => 0, type => 'varchar(200)', default => ''}, - Type => - {read => 1, write => 1, sql_type => 12, length => 200, is_blob => 0, is_numeric => 0, type => 'varchar(200)', default => ''}, - RenderType => - {read => 1, write => 1, sql_type => 12, length => 64, is_blob => 0, is_numeric => 0, type => 'varchar(64)', default => ''}, - MaxValues => - {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''}, - Pattern => - {read => 1, write => 1, sql_type => -4, length => 0, is_blob => 1, is_numeric => 0, type => 'text', default => ''}, - Repeated => - {read => 1, write => 1, sql_type => 5, length => 6, is_blob => 0, is_numeric => 1, type => 'smallint(6)', default => '0'}, - ValuesClass => - {read => 1, write => 1, sql_type => 12, length => 64, is_blob => 0, is_numeric => 0, type => 'varchar(64)', default => ''}, - BasedOn => - {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''}, - Description => - {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''}, - SortOrder => - {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, - LookupType => - {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''}, - Creator => - {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, - Created => - {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''}, - LastUpdatedBy => - {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'}, - LastUpdated => - {read => 1, auto => 1, sql_type => 11, length => 0, is_blob => 0, is_numeric => 0, type => 'datetime', default => ''}, - Disabled => - {read => 1, write => 1, sql_type => 5, length => 6, is_blob => 0, is_numeric => 1, type => 'smallint(6)', default => '0'}, - - } -}; - - -RT::Base->_ImportOverlays(); - -1; |