Upgrade to 4.0.10.
[usit-rt.git] / lib / RT / Topic.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
49use warnings;
50use strict;
51
52package RT::Topic;
53use base 'RT::Record';
54
55sub Table {'Topics'}
56
57# {{{ Create
58
59=head2 Create PARAMHASH
60
61Create takes a hash of values and creates a row in the database:
62
63 int(11) 'Parent'.
64 varchar(255) 'Name'.
65 varchar(255) 'Description'.
66 varchar(64) 'ObjectType'.
67 int(11) 'ObjectId'.
68
69=cut
70
71sub Create {
72 my $self = shift;
73 my %args = (
74 Parent => '',
75 Name => '',
76 Description => '',
77 ObjectType => '',
78 ObjectId => '0',
79 @_);
80
81 my $obj = $RT::System;
82 if ($args{ObjectId}) {
83 $obj = $args{ObjectType}->new($self->CurrentUser);
84 $obj->Load($args{ObjectId});
85 $obj = $RT::System unless $obj->id;
86 }
87
88 return ( 0, $self->loc("Permission denied"))
89 unless ( $self->CurrentUser->HasRight(
90 Right => "AdminTopics",
91 Object => $obj,
92 EquivObjects => [ $RT::System, $obj ],
93 ) );
94
95 $self->SUPER::Create(@_);
96}
97
98# }}}
99
100
101# {{{ Delete
102
103=head2 Delete
104
105Deletes this topic, reparenting all sub-topics to this one's parent.
106
107=cut
108
109sub Delete {
110 my $self = shift;
111
112 unless ( $self->CurrentUserHasRight('AdminTopics') ) {
113 return ( 0, $self->loc("Permission Denied") );
114 }
115
116 my $kids = RT::Topics->new($self->CurrentUser);
117 $kids->LimitToKids($self->Id);
118 while (my $topic = $kids->Next) {
119 $topic->setParent($self->Parent);
120 }
121
122 $self->SUPER::Delete(@_);
123 return (0, "Topic deleted");
124}
125
126# }}}
127
128
129# {{{ DeleteAll
130
131=head2 DeleteAll
132
133Deletes this topic, and all of its descendants.
134
135=cut
136
137sub DeleteAll {
138 my $self = shift;
139
140 unless ( $self->CurrentUserHasRight('AdminTopics') ) {
141 return ( 0, $self->loc("Permission Denied") );
142 }
143
144 $self->SUPER::Delete(@_);
145 my $kids = RT::Topics->new($self->CurrentUser);
146 $kids->LimitToKids($self->Id);
147 while (my $topic = $kids->Next) {
148 $topic->DeleteAll;
149 }
150
151 return (0, "Topic tree deleted");
152}
153
154# }}}
155
156
157# {{{ ParentObj
158
159=head2 ParentObj
160
161Returns the parent Topic of this one.
162
163=cut
164
165sub ParentObj {
166 my $self = shift;
167 my $id = $self->Parent;
168 my $obj = RT::Topic->new($self->CurrentUser);
169 $obj->Load($id);
170 return $obj;
171}
172
173# }}}
174
175# {{{ Children
176
177=head2 Children
178
179Returns a Topics object containing this topic's children,
180sorted by Topic.Name.
181
182=cut
183
184sub Children {
185 my $self = shift;
186 unless ($self->{'Children'}) {
187 $self->{'Children'} = RT::Topics->new($self->CurrentUser);
188 $self->{'Children'}->Limit('FIELD' => 'Parent',
189 'VALUE' => $self->Id);
190 $self->{'Children'}->OrderBy('FIELD' => 'Name');
191 }
192 return $self->{'Children'};
193}
194
195# {{{ _Set
196
197=head2 _Set
198
199Intercept attempts to modify the Topic so we can apply ACLs
200
201=cut
202
203sub _Set {
204 my $self = shift;
205
206 unless ( $self->CurrentUserHasRight('AdminTopics') ) {
207 return ( 0, $self->loc("Permission Denied") );
208 }
209 $self->SUPER::_Set(@_);
210}
211
212# }}}
213
214
215# {{{ CurrentUserHasRight
216
217=head2 CurrentUserHasRight
218
219Returns true if the current user has the right for this topic, for the
220whole system or for whatever object this topic is associated with
221
222=cut
223
224sub CurrentUserHasRight {
225 my $self = shift;
226 my $right = shift;
227
228 my $equiv = [ $RT::System ];
229 if ($self->ObjectId) {
230 my $obj = $self->ObjectType->new($self->CurrentUser);
231 $obj->Load($self->ObjectId);
232 push @{$equiv}, $obj;
233 }
234 if ($self->Id) {
235 return ( $self->CurrentUser->HasRight(
236 Right => $right,
237 Object => $self,
238 EquivObjects => $equiv,
239 ) );
240 } else {
241 # If we don't have an ID, we don't even know what object we're
242 # attached to -- so the only thing we can fall back on is the
243 # system object.
244 return ( $self->CurrentUser->HasRight(
245 Right => $right,
246 Object => $RT::System,
247 ) );
248 }
249
250
251}
252
253# }}}
254
255
256=head2 id
257
258Returns the current value of id.
259(In the database, id is stored as int(11).)
260
261
262=cut
263
264
265=head2 Parent
266
267Returns the current value of Parent.
268(In the database, Parent is stored as int(11).)
269
270
271
272=head2 SetParent VALUE
273
274
275Set Parent to VALUE.
276Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
277(In the database, Parent will be stored as a int(11).)
278
279
280=cut
281
282
283=head2 Name
284
285Returns the current value of Name.
286(In the database, Name is stored as varchar(255).)
287
288
289
290=head2 SetName VALUE
291
292
293Set Name to VALUE.
294Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
295(In the database, Name will be stored as a varchar(255).)
296
297
298=cut
299
300
301=head2 Description
302
303Returns the current value of Description.
304(In the database, Description is stored as varchar(255).)
305
306
307
308=head2 SetDescription VALUE
309
310
311Set Description to VALUE.
312Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
313(In the database, Description will be stored as a varchar(255).)
314
315
316=cut
317
318
319=head2 ObjectType
320
321Returns the current value of ObjectType.
322(In the database, ObjectType is stored as varchar(64).)
323
324
325
326=head2 SetObjectType VALUE
327
328
329Set ObjectType to VALUE.
330Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
331(In the database, ObjectType will be stored as a varchar(64).)
332
333
334=cut
335
336
337=head2 ObjectId
338
339Returns the current value of ObjectId.
340(In the database, ObjectId is stored as int(11).)
341
342
343
344=head2 SetObjectId VALUE
345
346
347Set ObjectId to VALUE.
348Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
349(In the database, ObjectId will be stored as a int(11).)
350
351
352=cut
353
354
355
356sub _CoreAccessible {
357 {
358
359 id =>
360 {read => 1, type => 'int(11)', default => ''},
361 Parent =>
362 {read => 1, write => 1, type => 'int(11)', default => ''},
363 Name =>
364 {read => 1, write => 1, type => 'varchar(255)', default => ''},
365 Description =>
366 {read => 1, write => 1, type => 'varchar(255)', default => ''},
367 ObjectType =>
368 {read => 1, write => 1, type => 'varchar(64)', default => ''},
369 ObjectId =>
370 {read => 1, write => 1, type => 'int(11)', default => '0'},
371
372 }
373};
374
375RT::Base->_ImportOverlays();
3761;