summaryrefslogtreecommitdiff
path: root/rt/lib/RT/CustomFieldValues
diff options
context:
space:
mode:
Diffstat (limited to 'rt/lib/RT/CustomFieldValues')
-rw-r--r--rt/lib/RT/CustomFieldValues/External.pm219
-rw-r--r--rt/lib/RT/CustomFieldValues/Groups.pm80
-rw-r--r--rt/lib/RT/CustomFieldValues/Queues.pm30
3 files changed, 329 insertions, 0 deletions
diff --git a/rt/lib/RT/CustomFieldValues/External.pm b/rt/lib/RT/CustomFieldValues/External.pm
new file mode 100644
index 000000000..81aaa2b2c
--- /dev/null
+++ b/rt/lib/RT/CustomFieldValues/External.pm
@@ -0,0 +1,219 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 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::CustomFieldValues::External;
+
+use strict;
+use warnings;
+
+use base qw(RT::CustomFieldValues);
+
+=head1 NAME
+
+RT::CustomFieldValues::External - Pull possible values for a custom
+field from an arbitrary external data source.
+
+=head1 SYNOPSIS
+
+Custom field value lists can be produced by creating a class that
+inherits from C<RT::CustomFieldValues::External>, and overloading
+C<SourceDescription> and C<ExternalValues>. See
+L<RT::CustomFieldValues::Groups> for a simple example.
+
+=head1 DESCRIPTION
+
+Subclasses should implement the following methods:
+
+=head2 SourceDescription
+
+This method should return a string describing the data source; this is
+the identifier by which the user will see the dropdown.
+
+=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>.
+
+=head1 SEE ALSO
+
+L<docs/creating_external_custom_fields.pod>
+
+=cut
+
+sub _Init {
+ my $self = shift;
+ $self->Table( '' );
+ return ( $self->SUPER::_Init(@_) );
+}
+
+sub CleanSlate {
+ my $self = shift;
+ delete $self->{ $_ } foreach qw(
+ __external_cf
+ __external_cf_limits
+ );
+ return $self->SUPER::CleanSlate(@_);
+}
+
+sub _ClonedAttributes {
+ my $self = shift;
+ return qw(
+ __external_cf
+ __external_cf_limits
+ ), $self->SUPER::_ClonedAttributes;
+}
+
+sub Limit {
+ my $self = shift;
+ my %args = (@_);
+ push @{ $self->{'__external_cf_limits'} ||= [] }, {
+ %args,
+ CALLBACK => $self->__BuildLimitCheck( %args ),
+ };
+ return $self->SUPER::Limit( %args );
+}
+
+sub __BuildLimitCheck {
+ my ($self, %args) = (@_);
+ return undef unless $args{'FIELD'} =~ /^(?:Name|Description)$/;
+
+ 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 (rc($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 => sub { defined $_[0] ? ($_[0] || $_[1]) : $_[1] },
+ AND => sub { defined $_[0] ? ($_[0] && $_[1]) : $_[1] },
+ );
+
+ return sub {
+ my ($sb, $record) = @_;
+ my $ok;
+ for my $limit ( @cbs ) {
+ $ok = $h{$limit->{ENTRYAGGREGATOR} || 'OR'}->(
+ $ok, $limit->{CALLBACK}->($record),
+ );
+ }
+ return $ok;
+ };
+}
+
+sub _DoSearch {
+ my $self = shift;
+
+ delete $self->{'items'};
+
+ my %defaults = (
+ id => 1,
+ name => '',
+ customfield => $self->{'__external_cf'},
+ sortorder => 0,
+ description => '',
+ creator => $RT::SystemUser->id,
+ created => undef,
+ lastupdatedby => $RT::SystemUser->id,
+ lastupdated => undef,
+ );
+
+ my $i = 0;
+
+ my $check = $self->__BuildAggregatorsCheck;
+ foreach( @{ $self->ExternalValues } ) {
+ my $value = $self->NewItem;
+ $value->LoadFromHash( { %defaults, %$_ } );
+ next if $check && !$check->( $self, $value );
+ $self->AddRecord( $value );
+ }
+ $self->{'must_redo_search'} = 0;
+ return $self->_RecordCount;
+}
+
+sub _DoCount {
+ my $self = shift;
+
+ my $count;
+ $count = $self->_DoSearch if $self->{'must_redo_search'};
+ $count = $self->_RecordCount unless defined $count;
+
+ return $self->{'count_all'} = $self->{'raw_rows'} = $count;
+}
+
+sub LimitToCustomField {
+ my $self = shift;
+ $self->{'__external_cf'} = $_[0];
+ return $self->SUPER::LimitToCustomField( @_ );
+}
+
+RT::Base->_ImportOverlays();
+
+1;
diff --git a/rt/lib/RT/CustomFieldValues/Groups.pm b/rt/lib/RT/CustomFieldValues/Groups.pm
new file mode 100644
index 000000000..59e31048b
--- /dev/null
+++ b/rt/lib/RT/CustomFieldValues/Groups.pm
@@ -0,0 +1,80 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 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::CustomFieldValues::Groups;
+
+use strict;
+use warnings;
+
+use base qw(RT::CustomFieldValues::External);
+
+sub SourceDescription {
+ return 'RT user defined groups';
+}
+
+sub ExternalValues {
+ my $self = shift;
+
+ my @res;
+ my $i = 0;
+ my $groups = RT::Groups->new( $self->CurrentUser );
+ $groups->LimitToUserDefinedGroups;
+ $groups->OrderByCols( { FIELD => 'Name' } );
+ while( my $group = $groups->Next ) {
+ push @res, {
+ name => $group->Name,
+ description => $group->Description,
+ sortorder => $i++,
+ };
+ }
+ return \@res;
+}
+
+RT::Base->_ImportOverlays();
+
+1;
diff --git a/rt/lib/RT/CustomFieldValues/Queues.pm b/rt/lib/RT/CustomFieldValues/Queues.pm
new file mode 100644
index 000000000..59529b6ac
--- /dev/null
+++ b/rt/lib/RT/CustomFieldValues/Queues.pm
@@ -0,0 +1,30 @@
+package RT::CustomFieldValues::Queues;
+
+use strict;
+use warnings;
+
+use base qw(RT::CustomFieldValues::External);
+
+sub SourceDescription {
+ return 'RT ticket queues';
+}
+
+sub ExternalValues {
+ my $self = shift;
+
+ my @res;
+ my $i = 0;
+ my $queues = RT::Queues->new( $self->CurrentUser );
+ $queues->UnLimit;
+ $queues->OrderByCols( { FIELD => 'Name' } );
+ while( my $queue = $queues->Next ) {
+ push @res, {
+ name => $queue->Name,
+ description => $queue->Description,
+ sortorder => $i++,
+ };
+ }
+ return \@res;
+}
+
+1;