diff options
Diffstat (limited to 'rt/lib/RT/Link.pm')
| -rw-r--r-- | rt/lib/RT/Link.pm | 487 | 
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; +  | 
