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.pm487
1 files changed, 279 insertions, 208 deletions
diff --git a/rt/lib/RT/Link.pm b/rt/lib/RT/Link.pm
index 962c378a8..885ffe3ed 100644
--- a/rt/lib/RT/Link.pm
+++ b/rt/lib/RT/Link.pm
@@ -1,302 +1,373 @@
-# BEGIN LICENSE BLOCK
-#
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-#
-# (Except where explictly superceded by other copyright notices)
-#
-# This work is made available to you under the terms of Version 2 of
-# the GNU General Public License. A copy of that license should have
-# been provided with this software, but in any event can be snarfed
-# from www.gnu.org.
-#
-# This work is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-#
-#
-# END LICENSE BLOCK
-# Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
-# WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.
-#
-# !! DO NOT EDIT THIS FILE !!
-#
-
-use strict;
-
+# $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
-
+ 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
-=cut
-package RT::Link;
-use RT::Record;
+=begin testing
+ok (require RT::TestHarness);
+ok (require RT::Link);
-use vars qw( @ISA );
-@ISA= qw( RT::Record );
+=end testing
-sub _Init {
- my $self = shift;
+=cut
- $self->Table('Links');
- $self->SUPER::_Init(@_);
+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
-
-=item Create PARAMHASH
-
-Create takes a hash of values and creates a row in the database:
-
- varchar(240) 'Base'.
- varchar(240) 'Target'.
- varchar(20) 'Type'.
- int(11) 'LocalTarget'.
- int(11) 'LocalBase'.
+Create a new link object. Takes 'Base', 'Target' and 'Type'.
+Returns undef on failure or a Link Id on success.
=cut
-
-
-
-sub Create {
+sub Create {
my $self = shift;
- my %args = (
- Base => '',
- Target => '',
- Type => '',
- LocalTarget => '0',
- LocalBase => '0',
-
- @_);
- $self->SUPER::Create(
- Base => $args{'Base'},
- Target => $args{'Target'},
- Type => $args{'Type'},
- LocalTarget => $args{'LocalTarget'},
- LocalBase => $args{'LocalBase'},
-);
-
+ 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
-=item id
-
-Returns the current value of id.
-(In the database, id is stored as int(11).)
+ 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");
+ }
+}
-=item Base
-
-Returns the current value of Base.
-(In the database, Base is stored as varchar(240).)
+# }}}
+# {{{ sub TargetObj
+=head2 TargetObj
-=item SetBase VALUE
+=cut
+sub TargetObj {
+ my $self = shift;
+ return $self->_TicketObj('base',$self->Target);
+}
+# }}}
-Set Base to VALUE.
-Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, Base will be stored as a varchar(240).)
+# {{{ sub BaseObj
+=head2 BaseObj
=cut
-
-=item Target
-
-Returns the current value of Target.
-(In the database, Target is stored as varchar(240).)
-
+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));
+}
+# }}}
-=item SetTarget VALUE
+# Static methods:
+# {{{ sub BaseIsLocal
-Set Target to VALUE.
-Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, Target will be stored as a varchar(240).)
+=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);
+}
-=item Type
-
-Returns the current value of Type.
-(In the database, Type is stored as varchar(20).)
-
-
-
-=item SetType VALUE
+# }}}
+# {{{ sub TargetIsLocal
-Set Type to VALUE.
-Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, Type will be stored as a varchar(20).)
+=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);
+}
-=item LocalTarget
-
-Returns the current value of LocalTarget.
-(In the database, LocalTarget is stored as int(11).)
-
-
-
-=item SetLocalTarget VALUE
+# }}}
+# {{{ sub _IsLocal
-Set LocalTarget to VALUE.
-Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, LocalTarget will be stored as a int(11).)
+=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);
+ }
+}
+# }}}
-=item LocalBase
-
-Returns the current value of LocalBase.
-(In the database, LocalBase is stored as int(11).)
-
-
-
-=item SetLocalBase VALUE
+# {{{ sub BaseAsHREF
-Set LocalBase to VALUE.
-Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, LocalBase will be stored as a int(11).)
+=head2 BaseAsHREF
+Returns an HTTP url to access the base of this link
=cut
+sub BaseAsHREF {
+ my $self = shift;
+ return $self->AsHREF($self->Base);
+}
+# }}}
-=item LastUpdatedBy
+# {{{ sub TargetAsHREF
-Returns the current value of LastUpdatedBy.
-(In the database, LastUpdatedBy is stored as int(11).)
+=head2 TargetAsHREF
+return an HTTP url to access the target of this link
=cut
+sub TargetAsHREF {
+ my $self = shift;
+ return $self->AsHREF($self->Target);
+}
+# }}}
-=item LastUpdated
-
-Returns the current value of LastUpdated.
-(In the database, LastUpdated is stored as datetime.)
+# {{{ 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";
+ }
+ }
+}
+# }}}
-=item Creator
-
-Returns the current value of Creator.
-(In the database, Creator is stored as int(11).)
-
-
-=cut
-
+# {{{ sub CanonicalizeURI
-=item Created
+=head2 CanonicalizeURI
-Returns the current value of Created.
-(In the database, Created is stored as datetime.)
+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 _ClassAccessible {
- {
+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 {
- id =>
- {read => 1, type => 'int(11)', default => ''},
- Base =>
- {read => 1, write => 1, type => 'varchar(240)', default => ''},
- Target =>
- {read => 1, write => 1, type => 'varchar(240)', default => ''},
- Type =>
- {read => 1, write => 1, type => 'varchar(20)', default => ''},
- LocalTarget =>
- {read => 1, write => 1, type => 'int(11)', default => '0'},
- LocalBase =>
- {read => 1, write => 1, type => 'int(11)', default => '0'},
- LastUpdatedBy =>
- {read => 1, auto => 1, type => 'int(11)', default => '0'},
- LastUpdated =>
- {read => 1, auto => 1, type => 'datetime', default => ''},
- Creator =>
- {read => 1, auto => 1, type => 'int(11)', default => '0'},
- Created =>
- {read => 1, auto => 1, type => 'datetime', default => ''},
-
- }
-};
-
-
- eval "require RT::Link_Overlay";
- if ($@ && $@ !~ qr{^Can't locate RT/Link_Overlay.pm}) {
- die $@;
- };
-
- eval "require RT::Link_Vendor";
- if ($@ && $@ !~ qr{^Can't locate RT/Link_Vendor.pm}) {
- die $@;
- };
-
- eval "require RT::Link_Local";
- if ($@ && $@ !~ qr{^Can't locate RT/Link_Local.pm}) {
- die $@;
- };
-
-
-
+ #If we couldn't find a ticket, return undef.
+ return( undef);
+
+ }
-=head1 SEE ALSO
-
-This class allows "overlay" methods to be placed
-into the following files _Overlay is for a System overlay by the original author,
-_Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customizations.
-
-These overlay files can contain new subs or subs to replace existing subs in this module.
-
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line
-
- no warnings qw(redefine);
-
-so that perl does not kick and scream when you redefine a subroutine or variable in your overlay.
-
-RT::Link_Overlay, RT::Link_Vendor, RT::Link_Local
-
-=cut
+
+}
+# }}}
1;
+