summaryrefslogtreecommitdiff
path: root/rt/lib/RT/Link.pm
diff options
context:
space:
mode:
Diffstat (limited to 'rt/lib/RT/Link.pm')
-rw-r--r--rt/lib/RT/Link.pm373
1 files changed, 373 insertions, 0 deletions
diff --git a/rt/lib/RT/Link.pm b/rt/lib/RT/Link.pm
new file mode 100644
index 000000000..885ffe3ed
--- /dev/null
+++ b/rt/lib/RT/Link.pm
@@ -0,0 +1,373 @@
+# $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Link.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
+# (c) 1996-1999 Jesse Vincent <jesse@fsck.com>
+# This software is redistributable under the terms of the GNU GPL
+
+=head1 NAME
+
+ RT::Link - an RT Link object
+
+=head1 SYNOPSIS
+
+ use RT::Link;
+
+=head1 DESCRIPTION
+
+This module should never be called directly by client code. it's an internal module which
+should only be accessed through exported APIs in Ticket other similar objects.
+
+=head1 METHODS
+
+
+=begin testing
+
+ok (require RT::TestHarness);
+ok (require RT::Link);
+
+=end testing
+
+=cut
+
+package RT::Link;
+use RT::Record;
+use Carp;
+@ISA= qw(RT::Record);
+
+# {{{ sub _Init
+sub _Init {
+ my $self = shift;
+ $self->{'table'} = "Links";
+ return ($self->SUPER::_Init(@_));
+}
+
+# }}}
+
+# {{{ sub Create
+
+=head2 Create PARAMHASH
+
+Create a new link object. Takes 'Base', 'Target' and 'Type'.
+Returns undef on failure or a Link Id on success.
+
+=cut
+
+sub Create {
+ my $self = shift;
+ my %args = ( Base => undef,
+ Target => undef,
+ Type => undef,
+ @_ # get the real argumentlist
+ );
+
+ my $BaseURI = $self->CanonicalizeURI($args{'Base'});
+ my $TargetURI = $self->CanonicalizeURI($args{'Target'});
+
+ unless (defined $BaseURI) {
+ $RT::Logger->warning ("$self couldn't resolve base:'".$args{'Base'}.
+ "' into a URI\n");
+ return (undef);
+ }
+ unless (defined $TargetURI) {
+ $RT::Logger->warning ("$self couldn't resolve target:'".$args{'Target'}.
+ "' into a URI\n");
+ return(undef);
+ }
+
+ my $LocalBase = $self->_IsLocal($BaseURI);
+ my $LocalTarget = $self->_IsLocal($TargetURI);
+ my $id = $self->SUPER::Create(Base => "$BaseURI",
+ Target => "$TargetURI",
+ LocalBase => $LocalBase,
+ LocalTarget => $LocalTarget,
+ Type => $args{'Type'});
+ return ($id);
+}
+
+# }}}
+
+# {{{ sub Load
+
+=head2 Load
+
+ Load an RT::Link object from the database. Takes one parameter or three.
+ One parameter is the id of an entry in the links table. Three parameters are a tuple of (base, linktype, target);
+
+
+=cut
+
+sub Load {
+ my $self = shift;
+ my $identifier = shift;
+ my $linktype = shift if (@_);
+ my $target = shift if (@_);
+
+ if ($target) {
+ my $BaseURI = $self->CanonicalizeURI($identifier);
+ my $TargetURI = $self->CanonicalizeURI($target);
+ $self->LoadByCols( Base => $BaseURI,
+ Type => $linktype,
+ Target => $TargetURI
+ ) || return (0, "Couldn't load link");
+ }
+
+ elsif ($identifier =~ /^\d+$/) {
+ $self->LoadById($identifier) ||
+ return (0, "Couldn't load link");
+ }
+ else {
+ return (0, "That's not a numerical id");
+ }
+}
+
+# }}}
+
+# {{{ sub TargetObj
+
+=head2 TargetObj
+
+=cut
+
+sub TargetObj {
+ my $self = shift;
+ return $self->_TicketObj('base',$self->Target);
+}
+# }}}
+
+# {{{ sub BaseObj
+
+=head2 BaseObj
+
+=cut
+
+sub BaseObj {
+ my $self = shift;
+ return $self->_TicketObj('target',$self->Base);
+}
+# }}}
+
+# {{{ sub _TicketObj
+sub _TicketObj {
+ my $self = shift;
+ my $name = shift;
+ my $ref = shift;
+ my $tag="$name\_obj";
+
+ unless (exists $self->{$tag}) {
+
+ $self->{$tag}=RT::Ticket->new($self->CurrentUser);
+
+ #If we can get an actual ticket, load it up.
+ if ($self->_IsLocal($ref)) {
+ $self->{$tag}->Load($ref);
+ }
+ }
+ return $self->{$tag};
+}
+# }}}
+
+# {{{ sub _Accessible
+sub _Accessible {
+ my $self = shift;
+ my %Cols = (
+ LocalBase => 'read',
+ LocalTarget => 'read',
+ Base => 'read',
+ Target => 'read',
+ Type => 'read',
+ Creator => 'read/auto',
+ Created => 'read/auto',
+ LastUpdatedBy => 'read/auto',
+ LastUpdated => 'read/auto'
+ );
+ return($self->SUPER::_Accessible(@_, %Cols));
+}
+# }}}
+
+
+# Static methods:
+
+# {{{ sub BaseIsLocal
+
+=head2 BaseIsLocal
+
+Returns true if the base of this link is a local ticket
+
+=cut
+
+sub BaseIsLocal {
+ my $self = shift;
+ return $self->_IsLocal($self->Base);
+}
+
+# }}}
+
+# {{{ sub TargetIsLocal
+
+=head2 TargetIsLocal
+
+Returns true if the target of this link is a local ticket
+
+=cut
+
+sub TargetIsLocal {
+ my $self = shift;
+ return $self->_IsLocal($self->Target);
+}
+
+# }}}
+
+# {{{ sub _IsLocal
+
+=head2 _IsLocal URI
+
+When handed a URI returns the local ticket id if it\'s local. otherwise returns undef.
+
+=cut
+
+sub _IsLocal {
+ my $self = shift;
+ my $URI=shift;
+ unless ($URI) {
+ $RT::Logger->warning ("$self _IsLocal called without a URI\n");
+ return (undef);
+ }
+ # TODO: More thorough check
+ if ($URI =~ /^$RT::TicketBaseURI(\d+)$/) {
+ return($1);
+ }
+ else {
+ return (undef);
+ }
+}
+# }}}
+
+
+# {{{ sub BaseAsHREF
+
+=head2 BaseAsHREF
+
+Returns an HTTP url to access the base of this link
+
+=cut
+
+sub BaseAsHREF {
+ my $self = shift;
+ return $self->AsHREF($self->Base);
+}
+# }}}
+
+# {{{ sub TargetAsHREF
+
+=head2 TargetAsHREF
+
+return an HTTP url to access the target of this link
+
+=cut
+
+sub TargetAsHREF {
+ my $self = shift;
+ return $self->AsHREF($self->Target);
+}
+# }}}
+
+# {{{ sub AsHREF - Converts Link URIs to HTTP URLs
+=head2 URI
+
+Takes a URI and returns an http: url to access that object.
+
+=cut
+sub AsHREF {
+ my $self=shift;
+ my $URI=shift;
+ if ($self->_IsLocal($URI)) {
+ my $url=$RT::WebURL . "Ticket/Display.html?id=$URI";
+ return($url);
+ }
+ else {
+ my ($protocol) = $URI =~ m|(.*?)://|;
+ unless (exists $RT::URI2HTTP{$protocol}) {
+ $RT::Logger->warning("Linking for protocol $protocol not defined in the config file!");
+ return("");
+ }
+ return $RT::URI2HTTP{$protocol}->($URI);
+ }
+}
+
+# }}}
+
+# {{{ sub GetContent - gets the content from a link
+sub GetContent {
+ my ($self, $URI)= @_;
+ if ($self->_IsLocal($URI)) {
+ die "stub";
+ } else {
+ # Find protocol
+ if ($URI =~ m|^(.*?)://|) {
+ if (exists $RT::ContentFromURI{$1}) {
+ return $RT::ContentFromURI{$1}->($URI);
+ } else {
+ warn "No sub exists for fetching the content from a $1 in $URI";
+ }
+ } else {
+ warn "No protocol specified in $URI";
+ }
+ }
+}
+# }}}
+
+# {{{ sub CanonicalizeURI
+
+=head2 CanonicalizeURI
+
+Takes a single argument: some form of ticket identifier.
+Returns its canonicalized URI.
+
+Bug: ticket aliases can't have :// in them. URIs must have :// in them.
+
+=cut
+
+sub CanonicalizeURI {
+ my $self = shift;
+ my $id = shift;
+
+
+ #If it's a local URI, load the ticket object and return its URI
+ if ($id =~ /^$RT::TicketBaseURI/) {
+ my $ticket = new RT::Ticket($self->CurrentUser);
+ $ticket->Load($id);
+ #If we couldn't find a ticket, return undef.
+ return undef unless (defined $ticket->Id);
+ #$RT::Logger->debug("$self -> CanonicalizeURI was passed $id and returned ".$ticket->URI ." (uri)\n");
+ return ($ticket->URI);
+ }
+ #If it's a remote URI, we're going to punt for now
+ elsif ($id =~ '://' ) {
+ return ($id);
+ }
+
+ #If the base is an integer, load it as a ticket
+ elsif ( $id =~ /^\d+$/ ) {
+
+ #$RT::Logger->debug("$self -> CanonicalizeURI was passed $id. It's a ticket id.\n");
+ my $ticket = new RT::Ticket($self->CurrentUser);
+ $ticket->Load($id);
+ #If we couldn't find a ticket, return undef.
+ return undef unless (defined $ticket->Id);
+ #$RT::Logger->debug("$self returned ".$ticket->URI ." (id #)\n");
+ return ($ticket->URI);
+ }
+
+ #It's not a URI. It's not a numerical ticket ID
+ else {
+
+ #If we couldn't find a ticket, return undef.
+ return( undef);
+
+ }
+
+
+}
+
+# }}}
+
+1;
+