# BEGIN BPS TAGGED BLOCK {{{
-#
+#
# COPYRIGHT:
-#
-# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
-# <jesse@bestpractical.com>
-#
+#
+# This software is Copyright (c) 1996-2017 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
# 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::CustomFieldValues::External;
=head2 ExternalValues
This method should return an array reference of hash references. The
-hash references should contain keys for C<name>, C<description>, and
-C<sortorder>.
+hash references must contain a key for C<name> and can optionally contain
+keys for C<description>, C<sortorder>, and C<category>. If supplying a
+category, you must also set the category the custom field is based on in
+the custom field configuration page.
=head1 SEE ALSO
-L<docs/creating_external_custom_fields.pod>
+F<docs/extending/external_custom_fields.pod>
=cut
my ($self, %args) = (@_);
return undef unless $args{'FIELD'} =~ /^(?:Name|Description)$/;
- $args{'OPERATOR'} ||= '=';
- my $quoted_value = $args{'VALUE'};
- if ( $quoted_value ) {
- $quoted_value =~ s/'/\\'/g;
- $quoted_value = "'$quoted_value'";
- }
-
- my $code = <<END;
-my \$record = shift;
-my \$value = \$record->$args{'FIELD'};
-my \$condition = $quoted_value;
-END
-
- if ( $args{'OPERATOR'} =~ /^(?:=|!=|<>)$/ ) {
- $code .= 'return 0 unless defined $value;';
- my %h = ( '=' => ' eq ', '!=' => ' ne ', '<>' => ' ne ' );
- $code .= 'return 0 unless $value'. $h{ $args{'OPERATOR'} } .'$condition;';
- $code .= 'return 1;'
- }
- elsif ( $args{'OPERATOR'} =~ /^(?:LIKE|NOT LIKE)$/i ) {
- $code .= 'return 0 unless defined $value;';
- my %h = ( 'LIKE' => ' =~ ', 'NOT LIKE' => ' !~ ' );
- $code .= 'return 0 unless $value'. $h{ uc $args{'OPERATOR'} } .'/\Q$condition/i;';
- $code .= 'return 1;'
- }
- else {
- $code .= 'return 0;'
- }
- $code = "sub {$code}";
- my $cb = eval "$code";
- $RT::Logger->error( "Couldn't build callback '$code': $@" ) if $@;
- return $cb;
+ my $condition = $args{VALUE};
+ my $op = $args{'OPERATOR'} || '=';
+ my $field = $args{FIELD};
+
+ return sub {
+ my $record = shift;
+ my $value = $record->$field;
+ return 0 unless defined $value;
+ if ($op eq "=") {
+ return 0 unless $value eq $condition;
+ } elsif ($op eq "!=" or $op eq "<>") {
+ return 0 unless $value ne $condition;
+ } elsif (uc($op) eq "LIKE") {
+ return 0 unless $value =~ /\Q$condition\E/i;
+ } elsif (uc($op) eq "NOT LIKE") {
+ return 0 unless $value !~ /\Q$condition\E/i;
+ } else {
+ return 0;
+ }
+ return 1;
+ };
}
sub __BuildAggregatorsCheck {
my $self = shift;
+ my @cbs = grep {$_->{CALLBACK}} @{ $self->{'__external_cf_limits'} };
+ return undef unless @cbs;
- my %h = ( OR => ' || ', AND => ' && ' );
-
- my $code = '';
- for( my $i = 0; $i < @{ $self->{'__external_cf_limits'} }; $i++ ) {
- next unless $self->{'__external_cf_limits'}->[$i]->{'CALLBACK'};
- $code .= $h{ uc($self->{'__external_cf_limits'}->[$i]->{'ENTRYAGGREGATOR'} || 'OR') } if $code;
- $code .= '$sb->{\'__external_cf_limits\'}->['. $i .']->{\'CALLBACK\'}->($record)';
- }
- return unless $code;
+ my %h = (
+ OR => sub { defined $_[0] ? ($_[0] || $_[1]) : $_[1] },
+ AND => sub { defined $_[0] ? ($_[0] && $_[1]) : $_[1] },
+ );
- $code = "sub { my (\$sb,\$record) = (\@_); return $code }";
- my $cb = eval "$code";
- $RT::Logger->error( "Couldn't build callback '$code': $@" ) if $@;
- return $cb;
+ return sub {
+ my ($sb, $record) = @_;
+ my $ok;
+ for my $limit ( @cbs ) {
+ $ok = $h{$limit->{ENTRYAGGREGATOR} || 'OR'}->(
+ $ok, $limit->{CALLBACK}->($record),
+ );
+ }
+ return $ok;
+ };
}
sub _DoSearch {
customfield => $self->{'__external_cf'},
sortorder => 0,
description => '',
- creator => $RT::SystemUser->id,
+ category => undef,
+ creator => RT->SystemUser->id,
created => undef,
- lastupdatedby => $RT::SystemUser->id,
+ lastupdatedby => RT->SystemUser->id,
lastupdated => undef,
);
$value->LoadFromHash( { %defaults, %$_ } );
next if $check && !$check->( $self, $value );
$self->AddRecord( $value );
+ last if $self->RowsPerPage and ++$i >= $self->RowsPerPage;
}
$self->{'must_redo_search'} = 0;
return $self->_RecordCount;
return $self->SUPER::LimitToCustomField( @_ );
}
-eval "require RT::CustomFieldValues::External_Vendor";
-if ($@ && $@ !~ qr{^Can't locate RT/CustomFieldValues/External_Vendor.pm}) {
- die $@;
-};
+sub _SingularClass {
+ "RT::CustomFieldValue"
+}
-eval "require RT::CustomFieldValues::External_Local";
-if ($@ && $@ !~ qr{^Can't locate RT/CustomFieldValues/External_Local.pm}) {
- die $@;
-};
+RT::Base->_ImportOverlays();
1;