1 # BEGIN BPS TAGGED BLOCK {{{
5 # This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
6 # <sales@bestpractical.com>
8 # (Except where explicitly superseded by other copyright notices)
13 # This work is made available to you under the terms of Version 2 of
14 # the GNU General Public License. A copy of that license should have
15 # been provided with this software, but in any event can be snarfed
18 # This work is distributed in the hope that it will be useful, but
19 # WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 # General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 # 02110-1301 or visit their web page on the internet at
27 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
30 # CONTRIBUTION SUBMISSION POLICY:
32 # (The following paragraph is not intended to limit the rights granted
33 # to you to modify and distribute this software under the terms of
34 # the GNU General Public License and is only of importance to you if
35 # you choose to contribute your changes and enhancements to the
36 # community by submitting them to Best Practical Solutions, LLC.)
38 # By intentionally submitting any modifications, corrections or
39 # derivatives to this work, or any other work intended for use with
40 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 # you are the copyright holder for those contributions and you grant
42 # Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
43 # royalty-free, perpetual, license to use, copy, create derivative
44 # works based on those contributions, and sublicense and distribute
45 # those contributions and any derivatives thereof.
47 # END BPS TAGGED BLOCK }}}
51 RT::CustomFields - a collection of RT CustomField objects
66 package RT::CustomFields;
71 use base 'RT::SearchBuilder';
75 sub Table { 'CustomFields'}
80 # By default, order by SortOrder
92 $self->{'with_disabled_column'} = 1;
94 return ( $self->SUPER::_Init(@_) );
97 =head2 LimitToGrouping
99 Limits this collection object to custom fields which appear under a
100 specified grouping by calling L</Limit> for each CF name as appropriate.
102 Requires an L<RT::Record> object or class name as the first argument and
103 accepts a grouping name as the second. If the grouping name is false
104 (usually via the empty string), limits to custom fields which appear in no
107 I<Caveat:> While the record object or class name is used to find the
108 available groupings, no automatic limit is placed on the lookup type of
109 the custom fields. It's highly suggested you limit the collection by
110 queue or another lookup type first. This is already done for you if
111 you're creating the collection via the L</CustomFields> method on an
112 L<RT::Record> object.
116 sub LimitToGrouping {
119 my $grouping = shift;
121 my $config = RT->Config->Get('CustomFieldGroupings');
122 $config = {} unless ref($config) eq 'HASH';
123 $config = $config->{ref($obj) || $obj} || [];
124 my %h = ref $config eq "ARRAY" ? @{$config} : %{$config};
127 my $list = $h{$grouping};
128 unless ( $list and ref($list) eq 'ARRAY' and @$list ) {
129 return $self->Limit( FIELD => 'id', VALUE => 0, ENTRYAGGREGATOR => 'AND' );
132 $self->Limit( FIELD => 'Name', VALUE => $_, CASESENSITIVE => 0 );
135 my @list = map {@$_} grep defined && ref($_) eq 'ARRAY',
144 ENTRYAGGREGATOR => 'AND',
154 =head2 LimitToLookupType
156 Takes LookupType and limits collection.
160 sub LimitToLookupType {
164 $self->Limit( FIELD => 'LookupType', VALUE => "$lookup" );
167 =head2 LimitToChildType
169 Takes partial LookupType and limits collection to records
170 where LookupType is equal or ends with the value.
174 sub LimitToChildType {
178 $self->Limit( FIELD => 'LookupType', VALUE => "$lookup" );
179 $self->Limit( FIELD => 'LookupType', ENDSWITH => "$lookup" );
183 =head2 LimitToParentType
185 Takes partial LookupType and limits collection to records
186 where LookupType is equal or starts with the value.
190 sub LimitToParentType {
194 $self->Limit( FIELD => 'LookupType', VALUE => "$lookup" );
195 $self->Limit( FIELD => 'LookupType', STARTSWITH => "$lookup" );
198 =head2 LimitToObjectId
200 Takes an ObjectId and limits the collection to CFs applied to said object.
202 When called multiple times the ObjectId limits are joined with OR.
206 sub LimitToObjectId {
210 ALIAS => $self->_OCFAlias,
214 ENTRYAGGREGATOR => 'OR'
218 =head2 LimitToGlobalOrObjectId
220 Takes list of object IDs and limits collection to custom
221 fields that are added to these objects or globally.
225 sub LimitToGlobalOrObjectId {
230 foreach my $id (@_) {
231 $self->LimitToObjectId($id);
232 $global_only = 0 if $id;
235 $self->LimitToObjectId(0) unless $global_only;
238 =head2 LimitToNotAdded
240 Takes either list of object ids or nothing. Limits collection
241 to custom fields to listed objects or any corespondingly. Use
246 sub LimitToNotAdded {
248 return RT::ObjectCustomFields->new( $self->CurrentUser )
249 ->LimitTargetToNotAdded( $self => @_ );
254 Limits collection to custom fields to listed objects or any corespondingly. Use
261 return RT::ObjectCustomFields->new( $self->CurrentUser )
262 ->LimitTargetToAdded( $self => @_ );
265 =head2 LimitToGlobalOrQueue QUEUEID
267 Limits the set of custom fields found to global custom fields or those
268 tied to the queue C<QUEUEID>, similar to L</LimitToGlobalOrObjectId>.
270 Note that this will cause the collection to only return ticket CFs.
274 sub LimitToGlobalOrQueue {
277 $self->LimitToGlobalOrObjectId( $queue );
278 $self->LimitToLookupType( 'RT::Queue-RT::Ticket' );
282 =head2 LimitToQueue QUEUEID
284 Takes a numeric C<QUEUEID>, and limits the Custom Field collection to
285 those only applied directly to it; this limit is OR'd with other
286 L</LimitToQueue> and L</LimitToGlobal> limits.
288 Note that this will cause the collection to only return ticket CFs.
296 $self->Limit (ALIAS => $self->_OCFAlias,
297 ENTRYAGGREGATOR => 'OR',
301 $self->LimitToLookupType( 'RT::Queue-RT::Ticket' );
307 Limits the Custom Field collection to global ticket CFs; this limit is
308 OR'd with L</LimitToQueue> limits.
310 Note that this will cause the collection to only return ticket CFs.
317 $self->Limit (ALIAS => $self->_OCFAlias,
318 ENTRYAGGREGATOR => 'OR',
321 $self->LimitToLookupType( 'RT::Queue-RT::Ticket' );
325 =head2 ApplySortOrder
327 Sort custom fields according to thier order application to objects. It's
328 expected that collection contains only records of one
329 L<RT::CustomField/LookupType> and applied to one object or globally
330 (L</LimitToGlobalOrObjectId>), otherwise sorting makes no sense.
336 my $order = shift || 'ASC';
337 $self->OrderByCols( {
338 ALIAS => $self->_OCFAlias,
339 FIELD => 'SortOrder',
347 Returns context object for this collection of custom fields,
348 but only if it's defined.
354 return $self->{'context_object'};
358 =head2 SetContextObject
360 Sets context object for this collection of custom fields.
364 sub SetContextObject {
366 return $self->{'context_object'} = shift;
372 return RT::ObjectCustomFields->new( $self->CurrentUser )
373 ->JoinTargetToThis( $self => @_ );
379 Returns the next custom field that this user can see.
386 my $CF = $self->SUPER::Next();
387 return $CF unless $CF;
389 $CF->SetContextObject( $self->ContextObject );
391 return $self->Next unless $CF->CurrentUserHasRight('SeeCustomField');
397 Returns an empty new RT::CustomField item
398 Overrides <RT::SearchBuilder/NewItem> to make sure </ContextObject>
405 my $res = RT::CustomField->new($self->CurrentUser);
406 $res->SetContextObject($self->ContextObject);
410 RT::Base->_ImportOverlays();