#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2018 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
use strict;
use warnings;
+use base 'RT::Record';
use RT::Interface::Web;
use Regexp::Common qw(RE_net_IPv4);
# Allow the empty IPv6 address
$IPv6_re = qr/(?:$IPv6_re|::)/;
-
-
use RT::CustomField;
-use base 'RT::Record';
sub Table {'ObjectCustomFieldValues'}
@_,
);
+ my $cf = RT::CustomField->new( $self->CurrentUser );
+ $cf->Load( $args{CustomField} );
- my $cf_as_sys = RT::CustomField->new(RT->SystemUser);
- $cf_as_sys->Load($args{'CustomField'});
-
- if($cf_as_sys->Type eq 'IPAddress') {
- if ( $args{'Content'} ) {
- $args{'Content'} = $self->ParseIP( $args{'Content'} );
- }
-
- unless ( defined $args{'Content'} ) {
- return
- wantarray
- ? ( 0, $self->loc("Content is an invalid IP address") )
- : 0;
- }
- }
-
- if($cf_as_sys->Type eq 'IPAddressRange') {
- if ($args{'Content'}) {
- ($args{'Content'}, $args{'LargeContent'}) = $self->ParseIPRange( $args{'Content'} );
- }
- $args{'ContentType'} = 'text/plain';
-
- unless ( defined $args{'Content'} ) {
- return
- wantarray
- ? ( 0, $self->loc("Content is an invalid IP address range") )
- : 0;
- }
- }
+ my ($val, $msg) = $cf->_CanonicalizeValue(\%args);
+ return ($val, $msg) unless $val;
- if ( defined $args{'Content'} && length( Encode::encode_utf8($args{'Content'}) ) > 255 ) {
+ my $encoded = Encode::encode("UTF-8", $args{'Content'});
+ if ( defined $args{'Content'} && length( $encoded ) > 255 ) {
if ( defined $args{'LargeContent'} && length $args{'LargeContent'} ) {
$RT::Logger->error("Content is longer than 255 bytes and LargeContent specified");
}
else {
- $args{'LargeContent'} = $args{'Content'};
- $args{'Content'} = '';
+ # _EncodeLOB, and thus LargeContent, takes bytes; Content is
+ # in characters. Encode it; this may replace illegal
+ # codepoints (e.g. \x{FDD0}) with \x{FFFD}.
+ $args{'LargeContent'} = Encode::encode("UTF-8",$args{'Content'});
+ $args{'Content'} = undef;
$args{'ContentType'} ||= 'text/plain';
}
}
$self->_EncodeLOB( $args{'LargeContent'}, $args{'ContentType'} )
if defined $args{'LargeContent'};
- return $self->SUPER::Create(
+ ( my $id, $msg ) = $self->SUPER::Create(
CustomField => $args{'CustomField'},
ObjectType => $args{'ObjectType'},
ObjectId => $args{'ObjectId'},
ContentType => $args{'ContentType'},
ContentEncoding => $args{'ContentEncoding'},
);
+
+ if ( $id ) {
+ my $new_value = RT::ObjectCustomFieldValue->new( $self->CurrentUser );
+ $new_value->Load( $id );
+ my $ocfv_key = $new_value->GetOCFVCacheKey();
+ if ( $RT::ObjectCustomFieldValues::_OCFV_CACHE->{$ocfv_key} ) {
+ push @{ $RT::ObjectCustomFieldValues::_OCFV_CACHE->{$ocfv_key} },
+ {
+ 'ObjectId' => $new_value->Id,
+ 'CustomFieldObj' => $new_value->CustomFieldObj,
+ 'Content' => $new_value->_Value('Content'),
+ 'LargeContent' => $new_value->LargeContent,
+ };
+ }
+ }
+
+ return wantarray ? ( $id, $msg ) : $id;
}
if ( $args{CustomField} ) {
$cf = RT::CustomField->new( $self->CurrentUser );
$cf->Load( $args{CustomField} );
- if ( $cf->Type && $cf->Type eq 'IPAddressRange' ) {
-
- my ( $sIP, $eIP ) = $cf->ParseIPRange( $args{'Content'} );
- if ( $sIP && $eIP ) {
- $self->SUPER::LoadByCols( %args,
- Content => $sIP,
- LargeContent => $eIP
- );
- }
- }
+
+ my ($ok, $msg) = $cf->_CanonicalizeValue(\%args);
+ return ($ok, $msg) unless $ok;
}
return $self->SUPER::LoadByCols(%args);
}
sub Delete {
my $self = shift;
- return $self->SetDisabled(1);
+ my ( $ret, $msg ) = $self->SetDisabled( 1 );
+ if ( $ret ) {
+ my $ocfv_key = $self->GetOCFVCacheKey();
+ if ( $RT::ObjectCustomFieldValues::_OCFV_CACHE->{$ocfv_key} ) {
+ @{ $RT::ObjectCustomFieldValues::_OCFV_CACHE->{$ocfv_key} } =
+ grep { $_->{'ObjectId'} != $self->Id } @{ $RT::ObjectCustomFieldValues::_OCFV_CACHE->{$ocfv_key} };
+ }
+ }
+ return wantarray ? ( $ret, $msg ) : $ret;
}
=head2 _FillInTemplateURL URL
}
+=head2 GetOCFVCacheKey
+
+Get the OCFV cache key for this object
+
+=cut
+
+sub GetOCFVCacheKey {
+ my $self = shift;
+ my $ocfv_key = "CustomField-" . $self->CustomField
+ . '-ObjectType-' . $self->ObjectType
+ . '-ObjectId-' . $self->ObjectId;
+ return $ocfv_key;
+}
+
=head2 id
Returns the current value of id.
{
id =>
- {read => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''},
+ {read => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''},
CustomField =>
- {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''},
+ {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''},
ObjectType =>
- {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''},
+ {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''},
ObjectId =>
- {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''},
+ {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => ''},
SortOrder =>
- {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
+ {read => 1, write => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
Content =>
- {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''},
+ {read => 1, write => 1, sql_type => 12, length => 255, is_blob => 0, is_numeric => 0, type => 'varchar(255)', default => ''},
LargeContent =>
- {read => 1, write => 1, sql_type => -4, length => 0, is_blob => 1, is_numeric => 0, type => 'longblob', default => ''},
+ {read => 1, write => 1, sql_type => -4, length => 0, is_blob => 1, is_numeric => 0, type => 'longblob', default => ''},
ContentType =>
- {read => 1, write => 1, sql_type => 12, length => 80, is_blob => 0, is_numeric => 0, type => 'varchar(80)', default => ''},
+ {read => 1, write => 1, sql_type => 12, length => 80, is_blob => 0, is_numeric => 0, type => 'varchar(80)', default => ''},
ContentEncoding =>
- {read => 1, write => 1, sql_type => 12, length => 80, is_blob => 0, is_numeric => 0, type => 'varchar(80)', default => ''},
+ {read => 1, write => 1, sql_type => 12, length => 80, is_blob => 0, is_numeric => 0, type => 'varchar(80)', default => ''},
Creator =>
- {read => 1, auto => 1, sql_type => 4, length => 11, is_blob => 0, is_numeric => 1, type => 'int(11)', default => '0'},
+ {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 => ''},
+ {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'},
+ {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 => ''},
+ {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'},
+ {read => 1, write => 1, sql_type => 5, length => 6, is_blob => 0, is_numeric => 1, type => 'smallint(6)', default => '0'},
}
};
+sub FindDependencies {
+ my $self = shift;
+ my ($walker, $deps) = @_;
+
+ $self->SUPER::FindDependencies($walker, $deps);
+
+ $deps->Add( out => $self->CustomFieldObj );
+ $deps->Add( out => $self->Object );
+}
+
RT::Base->_ImportOverlays();
1;