import rt 3.6.6
[freeside.git] / rt / lib / RT / Link_Overlay.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2
3 # COPYRIGHT:
4 #  
5 # This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC 
6 #                                          <jesse@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/copyleft/gpl.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 =head1 NAME
49
50   RT::Link - an RT Link object
51
52 =head1 SYNOPSIS
53
54   use RT::Link;
55
56 =head1 DESCRIPTION
57
58 This module should never be called directly by client code. it's an internal module which
59 should only be accessed through exported APIs in Ticket other similar objects.
60
61 =head1 METHODS
62
63
64 =begin testing
65
66
67 use RT::Link;
68 my $link = RT::Link->new($RT::SystemUser);
69
70
71 ok (ref $link);
72 ok (UNIVERSAL::isa($link, 'RT::Link'));
73 ok (UNIVERSAL::isa($link, 'RT::Base'));
74 ok (UNIVERSAL::isa($link, 'RT::Record'));
75 ok (UNIVERSAL::isa($link, 'DBIx::SearchBuilder::Record'));
76
77 =end testing
78
79 =cut
80
81
82 package RT::Link;
83
84 use strict;
85 no warnings qw(redefine);
86
87
88 use Carp;
89 use RT::URI;
90
91
92 # {{{ sub Create 
93
94 =head2 Create PARAMHASH
95
96 Create a new link object. Takes 'Base', 'Target' and 'Type'.
97 Returns undef on failure or a Link Id on success.
98
99 =cut
100
101 sub Create {
102     my $self = shift;
103     my %args = ( Base   => undef,
104                  Target => undef,
105                  Type   => undef,
106                  @_ );
107
108     my $base = RT::URI->new( $self->CurrentUser );
109     $base->FromURI( $args{'Base'} );
110
111     unless ( $base->Resolver && $base->Scheme ) {
112         my $msg = $self->loc("Couldn't resolve base '[_1]' into a URI.", 
113                              $args{'Base'});
114         $RT::Logger->warning( "$self $msg\n" );
115
116         if (wantarray) {
117             return(undef, $msg);
118         } else {
119             return (undef);
120         }
121     }
122
123     my $target = RT::URI->new( $self->CurrentUser );
124     $target->FromURI( $args{'Target'} );
125
126     unless ( $target->Resolver ) {
127         my $msg = $self->loc("Couldn't resolve target '[_1]' into a URI.", 
128                              $args{'Target'});
129         $RT::Logger->warning( "$self $msg\n" );
130
131         if (wantarray) {
132             return(undef, $msg);
133         } else {
134             return (undef);
135         }
136     }
137
138     my $base_id   = 0;
139     my $target_id = 0;
140
141
142
143
144     if ( $base->IsLocal ) {
145         unless (UNIVERSAL::can($base->Object, 'Id')) {
146             return (undef, $self->loc("[_1] appears to be a local object, but can't be found in the database", $args{'Base'}));
147         
148         }
149         $base_id = $base->Object->Id;
150     }
151     if ( $target->IsLocal ) {
152         unless (UNIVERSAL::can($target->Object, 'Id')) {
153             return (undef, $self->loc("[_1] appears to be a local object, but can't be found in the database", $args{'Target'}));
154         
155         }
156         $target_id = $target->Object->Id;
157     }
158
159     # {{{ We don't want references to ourself
160     if ( $base->URI eq $target->URI ) {
161         return ( 0, $self->loc("Can't link a ticket to itself") );
162     }
163
164     # }}}
165
166     my ( $id, $msg ) = $self->SUPER::Create( Base        => $base->URI,
167                                              Target      => $target->URI,
168                                              LocalBase   => $base_id,
169                                              LocalTarget => $target_id,
170                                              Type        => $args{'Type'} );
171     return ( $id, $msg );
172 }
173
174 # }}}
175  # {{{ sub LoadByParams
176
177 =head2 LoadByParams
178
179   Load an RT::Link object from the database.  Takes three parameters
180   
181   Base => undef,
182   Target => undef,
183   Type =>undef
184  
185   Base and Target are expected to be integers which refer to Tickets or URIs
186   Type is the link type
187
188 =cut
189
190 sub LoadByParams {
191     my $self = shift;
192     my %args = ( Base   => undef,
193                  Target => undef,
194                  Type   => undef,
195                  @_ );
196
197     my $base = RT::URI->new($self->CurrentUser);
198     $base->FromURI( $args{'Base'} );
199
200     my $target = RT::URI->new($self->CurrentUser);
201     $target->FromURI( $args{'Target'} );
202     
203     unless ($base->Resolver && $target->Resolver) {
204         return ( 0, $self->loc("Couldn't load link") );
205     }
206
207
208     my ( $id, $msg ) = $self->LoadByCols( Base   => $base->URI,
209                                           Type   => $args{'Type'},
210                                           Target => $target->URI );
211
212     unless ($id) {
213         return ( 0, $self->loc("Couldn't load link") );
214     }
215 }
216
217 # }}}
218 # {{{ sub Load 
219
220 =head2 Load
221
222   Load an RT::Link object from the database.  Takes one parameter, the id of an entry in the links table.
223
224
225 =cut
226
227 sub Load {
228     my $self       = shift;
229     my $identifier = shift;
230
231
232
233
234     if ( $identifier !~ /^\d+$/ ) {
235         return ( 0, $self->loc("That's not a numerical id") );
236     }
237     else {
238         my ( $id, $msg ) = $self->LoadById($identifier);
239         unless ( $self->Id ) {
240             return ( 0, $self->loc("Couldn't load link") );
241         }
242         return ( $id, $msg );
243     }
244 }
245
246 # }}}
247
248
249 # {{{ TargetURI
250
251 =head2 TargetURI
252
253 returns an RT::URI object for the "Target" of this link.
254
255 =cut
256
257 sub TargetURI {
258     my $self = shift;
259     my $URI = RT::URI->new($self->CurrentUser);
260     $URI->FromURI($self->Target);
261     return ($URI);
262 }
263
264 # }}}
265 # {{{ sub TargetObj 
266
267 =head2 TargetObj
268
269 =cut
270
271 sub TargetObj {
272     my $self = shift;
273     return $self->TargetURI->Object;
274 }
275 # }}}
276
277 # {{{ BaseURI
278
279 =head2 BaseURI
280
281 returns an RT::URI object for the "Base" of this link.
282
283 =cut
284
285 sub BaseURI {
286     my $self = shift;
287     my $URI = RT::URI->new($self->CurrentUser);
288     $URI->FromURI($self->Base);
289     return ($URI);
290 }
291
292 # }}}
293 # {{{ sub BaseObj
294
295 =head2 BaseObj
296
297 =cut
298
299 sub BaseObj {
300   my $self = shift;
301   return $self->BaseURI->Object;
302 }
303 # }}}
304
305
306
307 # Static methods:
308
309 # {{{ sub BaseIsLocal
310
311 =head2 BaseIsLocal
312
313 Returns true if the base of this link is a local ticket
314
315 =cut
316
317 sub BaseIsLocal {
318   my $self = shift;
319   $RT::Logger->crit("Link::BaseIsLocal is deprecated in favor of Link->BaseURI->IsLocal at (". join(":",caller).")");
320   return $self->BaseURI->IsLocal;
321 }
322
323 # }}}
324
325 # {{{ sub TargetIsLocal
326
327 =head2 TargetIsLocal
328
329 Returns true if the target of this link is a local ticket
330
331 =cut
332
333 sub TargetIsLocal {
334   my $self = shift;
335   $RT::Logger->crit("Link::BaseIsLocal is deprecated in favor of Link->BaseURI->IsLocal at (". join(":",caller).")");
336   return $self->TargetURI->IsLocal;
337 }
338
339 # }}}
340
341
342 # {{{ sub BaseAsHREF 
343
344 =head2 BaseAsHREF
345
346 Returns an HTTP url to access the base of this link
347
348 =cut
349
350 sub BaseAsHREF {
351   my $self = shift;
352   $RT::Logger->crit("Link::BaseAsHREF deprecated in favor of ->BaseURI->AsHREF at (". join(":",caller).")");
353   return $self->BaseURI->AsHREF;
354 }
355 # }}}
356
357 # {{{ sub TargetAsHREF 
358
359 =head2 TargetAsHREF
360
361 return an HTTP url to access the target of this link
362
363 =cut
364
365 sub TargetAsHREF {
366   my $self = shift;
367   $RT::Logger->crit("Link::TargetAsHREF deprecated in favor of ->TargetURI->AsHREF at (". join(":",caller).")");
368   return $self->TargetURI->AsHREF;
369 }
370 # }}}
371
372 # {{{ sub AsHREF - Converts Link URIs to HTTP URLs
373
374 =head2 URI
375
376 Takes a URI and returns an http: url to access that object.
377
378 =cut
379
380
381 sub AsHREF {
382     my $self=shift;
383    
384     $RT::Logger->crit("AsHREF is gone. look at URI::HREF to figure out what to do with \$URI");
385 }
386
387 # }}}
388
389 1;
390