import rt 3.8.7
[freeside.git] / rt / lib / RT / Link_Overlay.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2
3 # COPYRIGHT:
4
5 # This software is Copyright (c) 1996-2009 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/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 no warnings qw(redefine);
73
74
75 use Carp;
76 use RT::URI;
77
78
79 # {{{ sub Create 
80
81 =head2 Create PARAMHASH
82
83 Create a new link object. Takes 'Base', 'Target' and 'Type'.
84 Returns undef on failure or a Link Id on success.
85
86 =cut
87
88 sub Create {
89     my $self = shift;
90     my %args = ( Base   => undef,
91                  Target => undef,
92                  Type   => undef,
93                  @_ );
94
95     my $base = RT::URI->new( $self->CurrentUser );
96     $base->FromURI( $args{'Base'} );
97
98     unless ( $base->Resolver && $base->Scheme ) {
99         my $msg = $self->loc("Couldn't resolve base '[_1]' into a URI.", 
100                              $args{'Base'});
101         $RT::Logger->warning( "$self $msg" );
102
103         if (wantarray) {
104             return(undef, $msg);
105         } else {
106             return (undef);
107         }
108     }
109
110     my $target = RT::URI->new( $self->CurrentUser );
111     $target->FromURI( $args{'Target'} );
112
113     unless ( $target->Resolver ) {
114         my $msg = $self->loc("Couldn't resolve target '[_1]' into a URI.", 
115                              $args{'Target'});
116         $RT::Logger->warning( "$self $msg" );
117
118         if (wantarray) {
119             return(undef, $msg);
120         } else {
121             return (undef);
122         }
123     }
124
125     my $base_id   = 0;
126     my $target_id = 0;
127
128
129
130
131     if ( $base->IsLocal ) {
132         my $object = $base->Object;
133         unless (UNIVERSAL::can($object, 'Id')) {
134             return (undef, $self->loc("[_1] appears to be a local object, but can't be found in the database", $args{'Base'}));
135         
136         }
137         $base_id = $object->Id if UNIVERSAL::isa($object, 'RT::Ticket');
138     }
139     if ( $target->IsLocal ) {
140         my $object = $target->Object;
141         unless (UNIVERSAL::can($object, 'Id')) {
142             return (undef, $self->loc("[_1] appears to be a local object, but can't be found in the database", $args{'Target'}));
143         
144         }
145         $target_id = $object->Id if UNIVERSAL::isa($object, 'RT::Ticket');
146     }
147
148     # {{{ We don't want references to ourself
149     if ( $base->URI eq $target->URI ) {
150         return ( 0, $self->loc("Can't link a ticket to itself") );
151     }
152
153     # }}}
154
155     my ( $id, $msg ) = $self->SUPER::Create( Base        => $base->URI,
156                                              Target      => $target->URI,
157                                              LocalBase   => $base_id,
158                                              LocalTarget => $target_id,
159                                              Type        => $args{'Type'} );
160     return ( $id, $msg );
161 }
162
163 # }}}
164  # {{{ sub LoadByParams
165
166 =head2 LoadByParams
167
168   Load an RT::Link object from the database.  Takes three parameters
169   
170   Base => undef,
171   Target => undef,
172   Type =>undef
173  
174   Base and Target are expected to be integers which refer to Tickets or URIs
175   Type is the link type
176
177 =cut
178
179 sub LoadByParams {
180     my $self = shift;
181     my %args = ( Base   => undef,
182                  Target => undef,
183                  Type   => undef,
184                  @_ );
185
186     my $base = RT::URI->new($self->CurrentUser);
187     $base->FromURI( $args{'Base'} );
188
189     my $target = RT::URI->new($self->CurrentUser);
190     $target->FromURI( $args{'Target'} );
191     
192     unless ($base->Resolver && $target->Resolver) {
193         return ( 0, $self->loc("Couldn't load link") );
194     }
195
196
197     my ( $id, $msg ) = $self->LoadByCols( Base   => $base->URI,
198                                           Type   => $args{'Type'},
199                                           Target => $target->URI );
200
201     unless ($id) {
202         return ( 0, $self->loc("Couldn't load link") );
203     }
204 }
205
206 # }}}
207 # {{{ sub Load 
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 # {{{ TargetURI
239
240 =head2 TargetURI
241
242 returns an RT::URI object for the "Target" of this link.
243
244 =cut
245
246 sub TargetURI {
247     my $self = shift;
248     my $URI = RT::URI->new($self->CurrentUser);
249     $URI->FromURI($self->Target);
250     return ($URI);
251 }
252
253 # }}}
254 # {{{ sub TargetObj 
255
256 =head2 TargetObj
257
258 =cut
259
260 sub TargetObj {
261     my $self = shift;
262     return $self->TargetURI->Object;
263 }
264 # }}}
265
266 # {{{ BaseURI
267
268 =head2 BaseURI
269
270 returns an RT::URI object for the "Base" of this link.
271
272 =cut
273
274 sub BaseURI {
275     my $self = shift;
276     my $URI = RT::URI->new($self->CurrentUser);
277     $URI->FromURI($self->Base);
278     return ($URI);
279 }
280
281 # }}}
282 # {{{ sub BaseObj
283
284 =head2 BaseObj
285
286 =cut
287
288 sub BaseObj {
289   my $self = shift;
290   return $self->BaseURI->Object;
291 }
292 # }}}
293
294 1;
295