X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Flib%2FRT%2FObjectCustomFieldValue_Overlay.pm;h=403d216ce27f39790b055ba392a97a89e9f82e81;hb=90edd8a914fd484e649fb0aa051dce7927bd6881;hp=ed86b11df9b4855b0f5bdab21814db3386ead45f;hpb=c648976f0b7975f2328ebd7ba8c711fad0ca4195;p=freeside.git diff --git a/rt/lib/RT/ObjectCustomFieldValue_Overlay.pm b/rt/lib/RT/ObjectCustomFieldValue_Overlay.pm index ed86b11df..403d216ce 100644 --- a/rt/lib/RT/ObjectCustomFieldValue_Overlay.pm +++ b/rt/lib/RT/ObjectCustomFieldValue_Overlay.pm @@ -1,40 +1,40 @@ # BEGIN BPS TAGGED BLOCK {{{ -# +# # COPYRIGHT: -# -# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC -# -# +# +# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# +# # (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/copyleft/gpl.html. -# -# +# 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 @@ -43,66 +43,68 @@ # 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::ObjectCustomFieldValue; use strict; -no warnings qw(redefine); +use warnings; +use RT::Interface::Web; +no warnings qw(redefine); sub Create { my $self = shift; my %args = ( - CustomField => '0', - ObjectType => '', - ObjectId => '0', - Disabled => '0', - Content => '', - LargeContent => '', - ContentType => '', - ContentEncoding => '', - - @_); - - - if( $args{'Content'} && length($args{'Content'}) > 255 && !$args{'LargeContent'} ) { - - $args{'LargeContent'} = $args{'Content'}; - $args{'Content'} = ''; - $args{'ContentType'} = 'text/plain'; + CustomField => 0, + ObjectType => '', + ObjectId => 0, + Disabled => 0, + Content => '', + LargeContent => undef, + ContentType => '', + ContentEncoding => '', + @_, + ); + + if ( defined $args{'Content'} && length( Encode::encode_utf8($args{'Content'}) ) > 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'} = ''; + $args{'ContentType'} ||= 'text/plain'; + } } ( $args{'ContentEncoding'}, $args{'LargeContent'} ) = - $self->_EncodeLOB( $args{'LargeContent'}, $args{'ContentType'} ) - if ( $args{'LargeContent'} ); - - $self->SUPER::Create( - CustomField => $args{'CustomField'}, - ObjectType => $args{'ObjectType'}, - ObjectId => $args{'ObjectId'}, - Disabled => $args{'Disabled'}, - Content => $args{'Content'}, - LargeContent => $args{'LargeContent'}, - ContentType => $args{'ContentType'}, - ContentEncoding => $args{'ContentEncoding'}, -); - - - + $self->_EncodeLOB( $args{'LargeContent'}, $args{'ContentType'} ) + if defined $args{'LargeContent'}; + + return $self->SUPER::Create( + CustomField => $args{'CustomField'}, + ObjectType => $args{'ObjectType'}, + ObjectId => $args{'ObjectId'}, + Disabled => $args{'Disabled'}, + Content => $args{'Content'}, + LargeContent => $args{'LargeContent'}, + ContentType => $args{'ContentType'}, + ContentEncoding => $args{'ContentEncoding'}, + ); } sub LargeContent { my $self = shift; - $self->_DecodeLOB( $self->ContentType, $self->ContentEncoding, - $self->_Value( 'LargeContent', decode_utf8 => 0 ) ); - + return $self->_DecodeLOB( + $self->ContentType, + $self->ContentEncoding, + $self->_Value( 'LargeContent', decode_utf8 => 0 ) + ); } - - - =head2 LoadByTicketContentAndCustomField { Ticket => TICKET, CustomField => CUSTOMFIELD, Content => CONTENT } Loads a custom field value by Ticket, Content and which CustomField it's tied to @@ -112,40 +114,54 @@ Loads a custom field value by Ticket, Content and which CustomField it's tied to sub LoadByTicketContentAndCustomField { my $self = shift; - my %args = ( Ticket => undef, - CustomField => undef, - Content => undef, - @_ - ); - - - $self->LoadByCols( Content => $args{'Content'}, - CustomField => $args{'CustomField'}, - ObjectType => 'RT::Ticket', - ObjectId => $args{'Ticket'}, - Disabled => 0 - ); - - + my %args = ( + Ticket => undef, + CustomField => undef, + Content => undef, + @_ + ); + + return $self->LoadByCols( + Content => $args{'Content'}, + CustomField => $args{'CustomField'}, + ObjectType => 'RT::Ticket', + ObjectId => $args{'Ticket'}, + Disabled => 0 + ); } sub LoadByObjectContentAndCustomField { my $self = shift; - my %args = ( Object => undef, - CustomField => undef, - Content => undef, - @_ - ); + my %args = ( + Object => undef, + CustomField => undef, + Content => undef, + @_ + ); my $obj = $args{'Object'} or return; - $self->LoadByCols( Content => $args{'Content'}, - CustomField => $args{'CustomField'}, - ObjectType => ref($obj), - ObjectId => $obj->Id, - Disabled => 0 - ); + return $self->LoadByCols( + Content => $args{'Content'}, + CustomField => $args{'CustomField'}, + ObjectType => ref($obj), + ObjectId => $obj->Id, + Disabled => 0 + ); +} + +=head2 CustomFieldObj + +Returns the CustomField Object which has the id returned by CustomField +=cut + +sub CustomFieldObj { + my $self = shift; + my $CustomField = RT::CustomField->new( $self->CurrentUser ); + $CustomField->SetContextObject( $self->Object ); + $CustomField->Load( $self->__Value('CustomField') ); + return $CustomField; } @@ -156,18 +172,16 @@ content, try "LargeContent" =cut - sub Content { my $self = shift; my $content = $self->SUPER::Content; - if (!$content && $self->ContentType eq 'text/plain') { - return $self->LargeContent(); + if ( !(defined $content && length $content) && $self->ContentType && $self->ContentType eq 'text/plain' ) { + return $self->LargeContent; } else { return $content; } } - =head2 Object Returns the object this value applies to @@ -176,9 +190,9 @@ Returns the object this value applies to sub Object { my $self = shift; - my $Object = $self->__Value('ObjectType')->new($self->CurrentUser); - $Object->Load($self->__Value('ObjectId')); - return($Object); + my $Object = $self->__Value('ObjectType')->new( $self->CurrentUser ); + $Object->LoadById( $self->__Value('ObjectId') ); + return $Object; } @@ -191,13 +205,13 @@ Disable this value. Used to remove "current" values from records while leaving t sub Delete { my $self = shift; - $self->SetDisabled(1); + return $self->SetDisabled(1); } =head2 _FillInTemplateURL URL Takes a URL containing placeholders and returns the URL as filled in for this -ObjectCustomFieldValue. +ObjectCustomFieldValue. The values for the placeholders will be URI-escaped. Available placeholders: @@ -211,21 +225,58 @@ The id of the object in question. The value of this custom field for the object in question. +=item __WebDomain__, __WebPort__, __WebPath__, __WebBaseURL__ and __WebURL__ + +The value of the config option. + =back =cut -sub _FillInTemplateURL { +{ +my %placeholders = ( + id => { value => sub { $_[0]->ObjectId }, escape => 1 }, + CustomField => { value => sub { $_[0]->Content }, escape => 1 }, + WebDomain => { value => sub { RT->Config->Get('WebDomain') } }, + WebPort => { value => sub { RT->Config->Get('WebPort') } }, + WebPath => { value => sub { RT->Config->Get('WebPath') } }, + WebBaseURL => { value => sub { RT->Config->Get('WebBaseURL') } }, + WebURL => { value => sub { RT->Config->Get('WebURL') } }, +); +sub _FillInTemplateURL { my $self = shift; - my $url = shift; - $url =~ s/__id__/@{[$self->ObjectId]}/g; - $url =~ s/__CustomField__/@{[$self->Content]}/g; + return undef unless defined $url && length $url; + + # special case, whole value should be an URL + if ( $url =~ /^__CustomField__/ ) { + my $value = $self->Content; + # protect from javascript: URLs + if ( $value =~ /^\s*javascript:/i ) { + my $object = $self->Object; + $RT::Logger->error( + "Dangerouse value with JavaScript in custom field '". $self->CustomFieldObj->Name ."'" + ." on ". ref($object) ." #". $object->id + ); + return undef; + } + $url =~ s/^__CustomField__/$value/; + } + + # default value, uri-escape + for my $key (keys %placeholders) { + $url =~ s{__${key}__}{ + my $value = $placeholders{$key}{'value'}->( $self ); + $value = '' if !defined($value); + RT::Interface::Web::EscapeURI(\$value) if $placeholders{$key}{'escape'}; + $value + }gxe; + } return $url; -} +} } =head2 ValueLinkURL @@ -256,7 +307,4 @@ sub IncludeContentForValue { return $self->_FillInTemplateURL($self->CustomFieldObj->IncludeContentForValue); } - - - 1;