starting to work...
[freeside.git] / rt / lib / RT / Link.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2 #
3 # COPYRIGHT:
4 #
5 # This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
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::Link - an RT Link object
52
53 =head1 SYNOPSIS
54
55   use RT::Link;
56
57 =head1 DESCRIPTION
58
59 This module should never be called directly by client code. it's an internal module which
60 should only be accessed through exported APIs in Ticket other similar objects.
61
62 =head1 METHODS
63
64
65
66 =cut
67
68
69 package RT::Link;
70
71 use strict;
72 use warnings;
73
74
75
76 use base 'RT::Record';
77
78 sub Table {'Links'}
79 use Carp;
80 use RT::URI;
81
82
83
84 =head2 Create PARAMHASH
85
86 Create a new link object. Takes 'Base', 'Target' and 'Type'.
87 Returns undef on failure or a Link Id on success.
88
89 =cut
90
91 sub Create {
92     my $self = shift;
93     my %args = ( Base   => undef,
94                  Target => undef,
95                  Type   => undef,
96                  @_ );
97
98     my $base = RT::URI->new( $self->CurrentUser );
99     $base->FromURI( $args{'Base'} );
100
101     unless ( $base->Resolver && $base->Scheme ) {
102         my $msg = $self->loc("Couldn't resolve base '[_1]' into a URI.", 
103                              $args{'Base'});
104         $RT::Logger->warning( "$self $msg" );
105
106         if (wantarray) {
107             return(undef, $msg);
108         } else {
109             return (undef);
110         }
111     }
112
113     my $target = RT::URI->new( $self->CurrentUser );
114     $target->FromURI( $args{'Target'} );
115
116     unless ( $target->Resolver ) {
117         my $msg = $self->loc("Couldn't resolve target '[_1]' into a URI.", 
118                              $args{'Target'});
119         $RT::Logger->warning( "$self $msg" );
120
121         if (wantarray) {
122             return(undef, $msg);
123         } else {
124             return (undef);
125         }
126     }
127
128     my $base_id   = 0;
129     my $target_id = 0;
130
131
132
133
134     if ( $base->IsLocal ) {
135         my $object = $base->Object;
136         unless (UNIVERSAL::can($object, 'Id')) {
137             return (undef, $self->loc("[_1] appears to be a local object, but can't be found in the database", $args{'Base'}));
138         
139         }
140         $base_id = $object->Id if UNIVERSAL::isa($object, 'RT::Ticket');
141     }
142     if ( $target->IsLocal ) {
143         my $object = $target->Object;
144         unless (UNIVERSAL::can($object, 'Id')) {
145             return (undef, $self->loc("[_1] appears to be a local object, but can't be found in the database", $args{'Target'}));
146         
147         }
148         $target_id = $object->Id if UNIVERSAL::isa($object, 'RT::Ticket');
149     }
150
151     # We don't want references to ourself
152     if ( $base->URI eq $target->URI ) {
153         return ( 0, $self->loc("Can't link a ticket to itself") );
154     }
155
156     # }}}
157
158     my ( $id, $msg ) = $self->SUPER::Create( Base        => $base->URI,
159                                              Target      => $target->URI,
160                                              LocalBase   => $base_id,
161                                              LocalTarget => $target_id,
162                                              Type        => $args{'Type'} );
163     return ( $id, $msg );
164 }
165
166  # sub LoadByParams
167
168 =head2 LoadByParams
169
170   Load an RT::Link object from the database.  Takes three parameters
171   
172   Base => undef,
173   Target => undef,
174   Type =>undef
175  
176   Base and Target are expected to be integers which refer to Tickets or URIs
177   Type is the link type
178
179 =cut
180
181 sub LoadByParams {
182     my $self = shift;
183     my %args = ( Base   => undef,
184                  Target => undef,
185                  Type   => undef,
186                  @_ );
187
188     my $base = RT::URI->new($self->CurrentUser);
189     $base->FromURI( $args{'Base'} );
190
191     my $target = RT::URI->new($self->CurrentUser);
192     $target->FromURI( $args{'Target'} );
193     
194     unless ($base->Resolver && $target->Resolver) {
195         return ( 0, $self->loc("Couldn't load link") );
196     }
197
198
199     my ( $id, $msg ) = $self->LoadByCols( Base   => $base->URI,
200                                           Type   => $args{'Type'},
201                                           Target => $target->URI );
202
203     unless ($id) {
204         return ( 0, $self->loc("Couldn't load link") );
205     }
206 }
207
208
209 =head2 Load
210
211   Load an RT::Link object from the database.  Takes one parameter, the id of an entry in the links table.
212
213
214 =cut
215
216 sub Load {
217     my $self       = shift;
218     my $identifier = shift;
219
220
221
222
223     if ( $identifier !~ /^\d+$/ ) {
224         return ( 0, $self->loc("That's not a numerical id") );
225     }
226     else {
227         my ( $id, $msg ) = $self->LoadById($identifier);
228         unless ( $self->Id ) {
229             return ( 0, $self->loc("Couldn't load link") );
230         }
231         return ( $id, $msg );
232     }
233 }
234
235
236
237
238 =head2 TargetURI
239
240 returns an RT::URI object for the "Target" of this link.
241
242 =cut
243
244 sub TargetURI {
245     my $self = shift;
246     my $URI = RT::URI->new($self->CurrentUser);
247     $URI->FromURI($self->Target);
248     return ($URI);
249 }
250
251
252 =head2 TargetObj
253
254 =cut
255
256 sub TargetObj {
257     my $self = shift;
258     return $self->TargetURI->Object;
259 }
260
261
262 =head2 BaseURI
263
264 returns an RT::URI object for the "Base" of this link.
265
266 =cut
267
268 sub BaseURI {
269     my $self = shift;
270     my $URI = RT::URI->new($self->CurrentUser);
271     $URI->FromURI($self->Base);
272     return ($URI);
273 }
274
275
276 =head2 BaseObj
277
278 =cut
279
280 sub BaseObj {
281   my $self = shift;
282   return $self->BaseURI->Object;
283 }
284
285
286 =head2 id
287
288 Returns the current value of id.
289 (In the database, id is stored as int(11).)
290
291
292 =cut
293
294
295 =head2 Base
296
297 Returns the current value of Base.
298 (In the database, Base is stored as varchar(240).)
299
300
301
302 =head2 SetBase VALUE
303
304
305 Set Base to VALUE.
306 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
307 (In the database, Base will be stored as a varchar(240).)
308
309
310 =cut
311
312
313 =head2 Target
314
315 Returns the current value of Target.
316 (In the database, Target is stored as varchar(240).)
317
318
319
320 =head2 SetTarget VALUE
321
322
323 Set Target to VALUE.
324 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
325 (In the database, Target will be stored as a varchar(240).)
326
327
328 =cut
329
330
331 =head2 Type
332
333 Returns the current value of Type.
334 (In the database, Type is stored as varchar(20).)
335
336
337
338 =head2 SetType VALUE
339
340
341 Set Type to VALUE.
342 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
343 (In the database, Type will be stored as a varchar(20).)
344
345
346 =cut
347
348
349 =head2 LocalTarget
350
351 Returns the current value of LocalTarget.
352 (In the database, LocalTarget is stored as int(11).)
353
354
355
356 =head2 SetLocalTarget VALUE
357
358
359 Set LocalTarget to VALUE.
360 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
361 (In the database, LocalTarget will be stored as a int(11).)
362
363
364 =cut
365
366
367 =head2 LocalBase
368
369 Returns the current value of LocalBase.
370 (In the database, LocalBase is stored as int(11).)
371
372
373
374 =head2 SetLocalBase VALUE
375
376
377 Set LocalBase to VALUE.
378 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
379 (In the database, LocalBase will be stored as a int(11).)
380
381
382 =cut
383
384
385 =head2 LastUpdatedBy
386
387 Returns the current value of LastUpdatedBy.
388 (In the database, LastUpdatedBy is stored as int(11).)
389
390
391 =cut
392
393
394 =head2 LastUpdated
395
396 Returns the current value of LastUpdated.
397 (In the database, LastUpdated is stored as datetime.)
398
399
400 =cut
401
402
403 =head2 Creator
404
405 Returns the current value of Creator.
406 (In the database, Creator is stored as int(11).)
407
408
409 =cut
410
411
412 =head2 Created
413
414 Returns the current value of Created.
415 (In the database, Created is stored as datetime.)
416
417
418 =cut
419
420
421
422 sub _CoreAccessible {
423     {
424
425         id =>
426                 {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
427         Base =>
428                 {read => 1, write => 1, sql_type => 12, length => 240,  is_blob => 0,  is_numeric => 0,  type => 'varchar(240)', default => ''},
429         Target =>
430                 {read => 1, write => 1, sql_type => 12, length => 240,  is_blob => 0,  is_numeric => 0,  type => 'varchar(240)', default => ''},
431         Type =>
432                 {read => 1, write => 1, sql_type => 12, length => 20,  is_blob => 0,  is_numeric => 0,  type => 'varchar(20)', default => ''},
433         LocalTarget =>
434                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
435         LocalBase =>
436                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
437         LastUpdatedBy =>
438                 {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
439         LastUpdated =>
440                 {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
441         Creator =>
442                 {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
443         Created =>
444                 {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
445
446  }
447 };
448
449 RT::Base->_ImportOverlays();
450
451 1;