]> git.uio.no Git - usit-rt.git/blame - lib/RT/CustomFields.pm
Putting 4.2.0 on top of 4.0.17
[usit-rt.git] / lib / RT / CustomFields.pm
CommitLineData
84fb5b46
MKG
1# BEGIN BPS TAGGED BLOCK {{{
2#
3# COPYRIGHT:
4#
403d7b0b 5# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
84fb5b46
MKG
6# <sales@bestpractical.com>
7#
8# (Except where explicitly superseded by other copyright notices)
9#
10#
11# LICENSE:
12#
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
16# from www.gnu.org.
17#
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.
22#
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.
28#
29#
30# CONTRIBUTION SUBMISSION POLICY:
31#
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.)
37#
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.
46#
47# END BPS TAGGED BLOCK }}}
48
49=head1 NAME
50
51 RT::CustomFields - a collection of RT CustomField objects
52
53=head1 SYNOPSIS
54
55 use RT::CustomFields;
56
57=head1 DESCRIPTION
58
59=head1 METHODS
60
61
62
63=cut
64
65
66package RT::CustomFields;
67
68use strict;
69use warnings;
70
af59614d 71use base 'RT::SearchBuilder';
84fb5b46
MKG
72
73use RT::CustomField;
74
84fb5b46
MKG
75sub Table { 'CustomFields'}
76
77sub _Init {
78 my $self = shift;
79
80 # By default, order by SortOrder
81 $self->OrderByCols(
af59614d
MKG
82 { ALIAS => 'main',
83 FIELD => 'SortOrder',
84 ORDER => 'ASC' },
85 { ALIAS => 'main',
86 FIELD => 'Name',
87 ORDER => 'ASC' },
88 { ALIAS => 'main',
89 FIELD => 'id',
90 ORDER => 'ASC' },
84fb5b46
MKG
91 );
92 $self->{'with_disabled_column'} = 1;
93
94 return ( $self->SUPER::_Init(@_) );
95}
96
af59614d
MKG
97=head2 LimitToGrouping
98
99Limits this collection object to custom fields which appear under a
100specified grouping by calling L</Limit> for each CF name as appropriate.
101
102Requires an L<RT::Record> object or class name as the first argument and
103accepts 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
105grouping.
106
107I<Caveat:> While the record object or class name is used to find the
108available groupings, no automatic limit is placed on the lookup type of
109the custom fields. It's highly suggested you limit the collection by
110queue or another lookup type first. This is already done for you if
111you're creating the collection via the L</CustomFields> method on an
112L<RT::Record> object.
113
114=cut
115
116sub LimitToGrouping {
117 my $self = shift;
118 my $obj = shift;
119 my $grouping = shift;
120
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};
125
126 if ( $grouping ) {
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' );
130 }
131 foreach ( @$list ) {
132 $self->Limit( FIELD => 'Name', VALUE => $_, CASESENSITIVE => 0 );
133 }
134 } else {
135 my @list = map {@$_} grep defined && ref($_) eq 'ARRAY',
136 values %h;
137
138 return unless @list;
139 foreach ( @list ) {
140 $self->Limit(
141 FIELD => 'Name',
142 OPERATOR => '!=',
143 VALUE => $_,
144 ENTRYAGGREGATOR => 'AND',
145 CASESENSITIVE => 0,
146 );
147 }
148
149 }
150 return;
151}
152
84fb5b46
MKG
153
154=head2 LimitToLookupType
155
156Takes LookupType and limits collection.
157
158=cut
159
160sub LimitToLookupType {
161 my $self = shift;
162 my $lookup = shift;
163
164 $self->Limit( FIELD => 'LookupType', VALUE => "$lookup" );
165}
166
167=head2 LimitToChildType
168
169Takes partial LookupType and limits collection to records
170where LookupType is equal or ends with the value.
171
172=cut
173
174sub LimitToChildType {
175 my $self = shift;
176 my $lookup = shift;
177
178 $self->Limit( FIELD => 'LookupType', VALUE => "$lookup" );
179 $self->Limit( FIELD => 'LookupType', ENDSWITH => "$lookup" );
180}
181
182
183=head2 LimitToParentType
184
185Takes partial LookupType and limits collection to records
186where LookupType is equal or starts with the value.
187
188=cut
189
190sub LimitToParentType {
191 my $self = shift;
192 my $lookup = shift;
193
194 $self->Limit( FIELD => 'LookupType', VALUE => "$lookup" );
195 $self->Limit( FIELD => 'LookupType', STARTSWITH => "$lookup" );
196}
197
01e3b242
MKG
198=head2 LimitToObjectId
199
200Takes an ObjectId and limits the collection to CFs applied to said object.
201
202When called multiple times the ObjectId limits are joined with OR.
203
204=cut
205
206sub LimitToObjectId {
207 my $self = shift;
208 my $id = shift;
209 $self->Limit(
210 ALIAS => $self->_OCFAlias,
211 FIELD => 'ObjectId',
212 OPERATOR => '=',
213 VALUE => $id || 0,
214 ENTRYAGGREGATOR => 'OR'
215 );
216}
84fb5b46
MKG
217
218=head2 LimitToGlobalOrObjectId
219
220Takes list of object IDs and limits collection to custom
af59614d 221fields that are added to these objects or globally.
84fb5b46
MKG
222
223=cut
224
225sub LimitToGlobalOrObjectId {
226 my $self = shift;
227 my $global_only = 1;
228
229
230 foreach my $id (@_) {
01e3b242
MKG
231 $self->LimitToObjectId($id);
232 $global_only = 0 if $id;
84fb5b46
MKG
233 }
234
01e3b242 235 $self->LimitToObjectId(0) unless $global_only;
84fb5b46
MKG
236}
237
af59614d 238=head2 LimitToNotAdded
84fb5b46
MKG
239
240Takes either list of object ids or nothing. Limits collection
241to custom fields to listed objects or any corespondingly. Use
242zero to mean global.
243
244=cut
245
af59614d 246sub LimitToNotAdded {
84fb5b46 247 my $self = shift;
af59614d
MKG
248 return RT::ObjectCustomFields->new( $self->CurrentUser )
249 ->LimitTargetToNotAdded( $self => @_ );
84fb5b46
MKG
250}
251
af59614d 252=head2 LimitToAdded
84fb5b46
MKG
253
254Limits collection to custom fields to listed objects or any corespondingly. Use
255zero to mean global.
256
257=cut
258
af59614d 259sub LimitToAdded {
84fb5b46 260 my $self = shift;
af59614d
MKG
261 return RT::ObjectCustomFields->new( $self->CurrentUser )
262 ->LimitTargetToAdded( $self => @_ );
84fb5b46
MKG
263}
264
265=head2 LimitToGlobalOrQueue QUEUEID
266
af59614d
MKG
267Limits the set of custom fields found to global custom fields or those
268tied to the queue C<QUEUEID>, similar to L</LimitToGlobalOrObjectId>.
84fb5b46 269
af59614d 270Note that this will cause the collection to only return ticket CFs.
84fb5b46
MKG
271
272=cut
273
274sub LimitToGlobalOrQueue {
275 my $self = shift;
276 my $queue = shift;
277 $self->LimitToGlobalOrObjectId( $queue );
278 $self->LimitToLookupType( 'RT::Queue-RT::Ticket' );
279}
280
281
282=head2 LimitToQueue QUEUEID
283
af59614d
MKG
284Takes a numeric C<QUEUEID>, and limits the Custom Field collection to
285those only applied directly to it; this limit is OR'd with other
286L</LimitToQueue> and L</LimitToGlobal> limits.
84fb5b46 287
af59614d 288Note that this will cause the collection to only return ticket CFs.
84fb5b46
MKG
289
290=cut
291
292sub LimitToQueue {
293 my $self = shift;
af59614d
MKG
294 my $queue = shift;
295
296 $self->Limit (ALIAS => $self->_OCFAlias,
297 ENTRYAGGREGATOR => 'OR',
298 FIELD => 'ObjectId',
299 VALUE => "$queue")
300 if defined $queue;
301 $self->LimitToLookupType( 'RT::Queue-RT::Ticket' );
84fb5b46
MKG
302}
303
304
305=head2 LimitToGlobal
306
af59614d
MKG
307Limits the Custom Field collection to global ticket CFs; this limit is
308OR'd with L</LimitToQueue> limits.
84fb5b46 309
af59614d 310Note that this will cause the collection to only return ticket CFs.
84fb5b46
MKG
311
312=cut
313
314sub LimitToGlobal {
315 my $self = shift;
316
317 $self->Limit (ALIAS => $self->_OCFAlias,
318 ENTRYAGGREGATOR => 'OR',
af59614d
MKG
319 FIELD => 'ObjectId',
320 VALUE => 0);
84fb5b46
MKG
321 $self->LimitToLookupType( 'RT::Queue-RT::Ticket' );
322}
323
324
325=head2 ApplySortOrder
326
327Sort custom fields according to thier order application to objects. It's
328expected that collection contains only records of one
329L<RT::CustomField/LookupType> and applied to one object or globally
330(L</LimitToGlobalOrObjectId>), otherwise sorting makes no sense.
331
332=cut
333
334sub ApplySortOrder {
335 my $self = shift;
336 my $order = shift || 'ASC';
337 $self->OrderByCols( {
338 ALIAS => $self->_OCFAlias,
339 FIELD => 'SortOrder',
340 ORDER => $order,
341 } );
342}
343
344
345=head2 ContextObject
346
347Returns context object for this collection of custom fields,
348but only if it's defined.
349
350=cut
351
352sub ContextObject {
353 my $self = shift;
354 return $self->{'context_object'};
355}
356
357
358=head2 SetContextObject
359
360Sets context object for this collection of custom fields.
361
362=cut
363
364sub SetContextObject {
365 my $self = shift;
366 return $self->{'context_object'} = shift;
367}
368
369
370sub _OCFAlias {
371 my $self = shift;
af59614d
MKG
372 return RT::ObjectCustomFields->new( $self->CurrentUser )
373 ->JoinTargetToThis( $self => @_ );
84fb5b46
MKG
374}
375
376
377=head2 Next
378
379Returns the next custom field that this user can see.
380
381=cut
382
383sub Next {
384 my $self = shift;
385
386 my $CF = $self->SUPER::Next();
387 return $CF unless $CF;
388
389 $CF->SetContextObject( $self->ContextObject );
390
391 return $self->Next unless $CF->CurrentUserHasRight('SeeCustomField');
392 return $CF;
393}
394
395=head2 NewItem
396
397Returns an empty new RT::CustomField item
398Overrides <RT::SearchBuilder/NewItem> to make sure </ContextObject>
399is inherited.
400
401=cut
402
403sub NewItem {
404 my $self = shift;
405 my $res = RT::CustomField->new($self->CurrentUser);
406 $res->SetContextObject($self->ContextObject);
407 return $res;
408}
409
410RT::Base->_ImportOverlays();
411
4121;