1 # BEGIN BPS TAGGED BLOCK {{{
5 # This software is Copyright (c) 1996-2017 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 $grouping_class = $self->NewItem->_GroupingClass($obj);
123 my $config = RT->Config->Get('CustomFieldGroupings');
124 $config = {} unless ref($config) eq 'HASH';
125 $config = $config->{$grouping_class} || [];
126 my %h = ref $config eq "ARRAY" ? @{$config} : %{$config};
129 my $list = $h{$grouping};
130 unless ( $list and ref($list) eq 'ARRAY' and @$list ) {
131 return $self->Limit( FIELD => 'id', VALUE => 0, ENTRYAGGREGATOR => 'AND' );
135 FUNCTION => 'LOWER(?)',
137 VALUE => [map {lc $_} @{$list}],
141 my @list = map {@$_} grep defined && ref($_) eq 'ARRAY',
148 FUNCTION => 'LOWER(?)',
149 OPERATOR => 'NOT IN',
150 VALUE => [ map {lc $_} @list ],
158 =head2 LimitToLookupType
160 Takes LookupType and limits collection.
164 sub LimitToLookupType {
168 $self->Limit( FIELD => 'LookupType', VALUE => "$lookup" );
171 =head2 LimitToChildType
173 Takes partial LookupType and limits collection to records
174 where LookupType is equal or ends with the value.
178 sub LimitToChildType {
182 $self->Limit( FIELD => 'LookupType', VALUE => "$lookup", OPERATOR => "ENDSWITH" );
186 =head2 LimitToParentType
188 Takes partial LookupType and limits collection to records
189 where LookupType is equal or starts with the value.
193 sub LimitToParentType {
197 $self->Limit( FIELD => 'LookupType', VALUE => "$lookup", OPERATOR => "STARTSWITH" );
200 =head2 LimitToObjectId
202 Takes an ObjectId and limits the collection to CFs applied to said object.
204 When called multiple times the ObjectId limits are joined with OR.
208 sub LimitToObjectId {
212 ALIAS => $self->_OCFAlias,
216 ENTRYAGGREGATOR => 'OR'
220 =head2 LimitToGlobalOrObjectId
222 Takes list of object IDs and limits collection to custom
223 fields that are added to these objects or globally.
227 sub LimitToGlobalOrObjectId {
232 foreach my $id (@_) {
233 $self->LimitToObjectId($id);
234 $global_only = 0 if $id;
237 $self->LimitToObjectId(0) unless $global_only;
240 =head2 LimitToNotAdded
242 Takes either list of object ids or nothing. Limits collection
243 to custom fields to listed objects or any corespondingly. Use
248 sub LimitToNotAdded {
250 return RT::ObjectCustomFields->new( $self->CurrentUser )
251 ->LimitTargetToNotAdded( $self => @_ );
256 Limits collection to custom fields to listed objects or any corespondingly. Use
263 return RT::ObjectCustomFields->new( $self->CurrentUser )
264 ->LimitTargetToAdded( $self => @_ );
267 =head2 LimitToGlobalOrQueue QUEUEID
269 Limits the set of custom fields found to global custom fields or those
270 tied to the queue C<QUEUEID>, similar to L</LimitToGlobalOrObjectId>.
272 Note that this will cause the collection to only return ticket CFs.
276 sub LimitToGlobalOrQueue {
279 $self->LimitToGlobalOrObjectId( $queue );
280 $self->LimitToLookupType( 'RT::Queue-RT::Ticket' );
284 =head2 LimitToQueue QUEUEID
286 Takes a numeric C<QUEUEID>, and limits the Custom Field collection to
287 those only applied directly to it; this limit is OR'd with other
288 L</LimitToQueue> and L</LimitToGlobal> limits.
290 Note that this will cause the collection to only return ticket CFs.
298 $self->Limit (ALIAS => $self->_OCFAlias,
299 ENTRYAGGREGATOR => 'OR',
303 $self->LimitToLookupType( 'RT::Queue-RT::Ticket' );
309 Limits the Custom Field collection to global ticket CFs; this limit is
310 OR'd with L</LimitToQueue> limits.
312 Note that this will cause the collection to only return ticket CFs.
319 $self->Limit (ALIAS => $self->_OCFAlias,
320 ENTRYAGGREGATOR => 'OR',
323 $self->LimitToLookupType( 'RT::Queue-RT::Ticket' );
327 =head2 ApplySortOrder
329 Sort custom fields according to thier order application to objects. It's
330 expected that collection contains only records of one
331 L<RT::CustomField/LookupType> and applied to one object or globally
332 (L</LimitToGlobalOrObjectId>), otherwise sorting makes no sense.
338 my $order = shift || 'ASC';
339 $self->OrderByCols( {
340 ALIAS => $self->_OCFAlias,
341 FIELD => 'SortOrder',
349 Returns context object for this collection of custom fields,
350 but only if it's defined.
356 return $self->{'context_object'};
360 =head2 SetContextObject
362 Sets context object for this collection of custom fields.
366 sub SetContextObject {
368 return $self->{'context_object'} = shift;
374 return RT::ObjectCustomFields->new( $self->CurrentUser )
375 ->JoinTargetToThis( $self => @_ );
381 Overrides the collection to ensure that only custom fields the user can
382 see are returned; also propagates down the L</ContextObject>.
390 $record->SetContextObject( $self->ContextObject );
391 return unless $record->CurrentUserHasRight('SeeCustomField');
392 return $self->SUPER::AddRecord( $record );
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();