[Rt-commit] rt branch, 4.2/link-api-refactoring, created. rt-4.0.6-449-g4effe0c

Thomas Sibley trs at bestpractical.com
Fri Aug 17 16:42:00 EDT 2012


The branch, 4.2/link-api-refactoring has been created
        at  4effe0cca3dc163e2d4444432245c48db6354f10 (commit)

- Log -----------------------------------------------------------------
commit 92d78a8606c28c265f5398541864db66e53c95d4
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Fri Aug 17 09:29:19 2012 -0700

    Code formatting, no functional changes

diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm
index e788e54..b772a25 100644
--- a/lib/RT/Record.pm
+++ b/lib/RT/Record.pm
@@ -1264,8 +1264,6 @@ sub FormatLink {
     return $text;
 }
 
-
-
 =head2 _AddLink
 
 Takes a paramhash of Type and one of Base or Target. Adds that link to this object.
@@ -1277,12 +1275,13 @@ Returns C<link id>, C<message> and C<exist> flag.
 
 sub _AddLink {
     my $self = shift;
-    my %args = ( Target => '',
-                 Base   => '',
-                 Type   => '',
-                 Silent => undef,
-                 @_ );
-
+    my %args = (
+        Target       => '',
+        Base         => '',
+        Type         => '',
+        Silent       => undef,
+        @_
+    );
 
     # Remote_link is the URI of the object that is not this ticket
     my $remote_link;
@@ -1317,32 +1316,26 @@ sub _AddLink {
         return ( $old_link->id, $self->loc("Link already exists"), 1 );
     }
 
-    # }}}
-
-
     # Storing the link in the DB.
     my $link = RT::Link->new( $self->CurrentUser );
     my ($linkid, $linkmsg) = $link->Create( Target => $args{Target},
-                                  Base   => $args{Base},
-                                  Type   => $args{Type} );
+                                            Base   => $args{Base},
+                                            Type   => $args{Type} );
 
     unless ($linkid) {
         $RT::Logger->error("Link could not be created: ".$linkmsg);
         return ( 0, $self->loc("Link could not be created") );
     }
 
-    my $basetext = $self->FormatLink(Object => $link->BaseObj,
-				     FallBack => $args{Base});
-    my $targettext = $self->FormatLink(Object => $link->TargetObj,
-				       FallBack => $args{Target});
+    my $basetext = $self->FormatLink(Object   => $link->BaseObj,
+                                     FallBack => $args{Base});
+    my $targettext = $self->FormatLink(Object   => $link->TargetObj,
+                                       FallBack => $args{Target});
     my $typetext = $self->FormatType(Type => $args{Type});
-    my $TransString =
-      "$basetext $typetext $targettext.";
+    my $TransString = "$basetext $typetext $targettext.";
     return ( $linkid, $TransString ) ;
 }
 
-
-
 =head2 _DeleteLink
 
 Delete a link. takes a paramhash of Base, Target and Type.
@@ -1360,9 +1353,7 @@ sub _DeleteLink {
         @_
     );
 
-    #we want one of base and target. we don't care which
-    #but we only want _one_
-
+    # We want one of base and target. We don't care which but we only want _one_.
     my $direction;
     my $remote_link;
 
@@ -1372,13 +1363,13 @@ sub _DeleteLink {
     }
     elsif ( $args{'Base'} ) {
         $args{'Target'} = $self->URI();
-	$remote_link = $args{'Base'};
-    	$direction = 'Target';
+        $remote_link    = $args{'Base'};
+        $direction      = 'Target';
     }
     elsif ( $args{'Target'} ) {
         $args{'Base'} = $self->URI();
-	$remote_link = $args{'Target'};
-        $direction='Base';
+        $remote_link  = $args{'Target'};
+        $direction    = 'Base';
     }
     else {
         $RT::Logger->error("Base or Target must be specified");
@@ -1386,17 +1377,23 @@ sub _DeleteLink {
     }
 
     my $link = RT::Link->new( $self->CurrentUser );
-    $RT::Logger->debug( "Trying to load link: " . $args{'Base'} . " " . $args{'Type'} . " " . $args{'Target'} );
-
-
-    $link->LoadByParams( Base=> $args{'Base'}, Type=> $args{'Type'}, Target=>  $args{'Target'} );
-    #it's a real link. 
+    $RT::Logger->debug( "Trying to load link: "
+            . $args{'Base'} . " "
+            . $args{'Type'} . " "
+            . $args{'Target'} );
+
+    $link->LoadByParams(
+        Base   => $args{'Base'},
+        Type   => $args{'Type'},
+        Target => $args{'Target'}
+    );
 
+    # it's a real link.
     if ( $link->id ) {
-        my $basetext = $self->FormatLink(Object => $link->BaseObj,
-                                     FallBack => $args{Base});
-        my $targettext = $self->FormatLink(Object => $link->TargetObj,
-                                       FallBack => $args{Target});
+        my $basetext = $self->FormatLink(Object   => $link->BaseObj,
+                                         FallBack => $args{Base});
+        my $targettext = $self->FormatLink(Object   => $link->TargetObj,
+                                           FallBack => $args{Target});
         my $typetext = $self->FormatType(Type => $args{Type});
         my $linkid = $link->id;
         $link->Delete();
@@ -1411,10 +1408,6 @@ sub _DeleteLink {
     }
 }
 
-
-
-
-
 =head2 _NewTransaction  PARAMHASH
 
 Private function to create a new RT::Transaction object for this ticket update

commit 7821ff1e221032408f6bad2386618ce96df5519f
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Fri Aug 17 11:22:11 2012 -0700

    Move creation of link transactions from RT::Ticket into RT::Record
    
    Now articles and other objects will record transactions for links.

diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm
index b772a25..6e6e87d 100644
--- a/lib/RT/Record.pm
+++ b/lib/RT/Record.pm
@@ -1268,8 +1268,11 @@ sub FormatLink {
 
 Takes a paramhash of Type and one of Base or Target. Adds that link to this object.
 
-Returns C<link id>, C<message> and C<exist> flag.
+If Silent is true then no transactions will be recorded.  You can individually
+control transactions on both base and target and with SilentBase and
+SilentTarget respectively. By default both transactions are created.
 
+Returns a tuple of (link ID, message, flag if link already existed).
 
 =cut
 
@@ -1280,6 +1283,9 @@ sub _AddLink {
         Base         => '',
         Type         => '',
         Silent       => undef,
+        Silent       => undef,
+        SilentBase   => undef,
+        SilentTarget => undef,
         @_
     );
 
@@ -1324,7 +1330,7 @@ sub _AddLink {
 
     unless ($linkid) {
         $RT::Logger->error("Link could not be created: ".$linkmsg);
-        return ( 0, $self->loc("Link could not be created") );
+        return ( 0, $self->loc("Link could not be created: [_1]", $linkmsg) );
     }
 
     my $basetext = $self->FormatLink(Object   => $link->BaseObj,
@@ -1333,23 +1339,62 @@ sub _AddLink {
                                        FallBack => $args{Target});
     my $typetext = $self->FormatType(Type => $args{Type});
     my $TransString = "$basetext $typetext $targettext.";
-    return ( $linkid, $TransString ) ;
+
+    # No transactions for you!
+    return ($linkid, $TransString) if $args{'Silent'};
+
+    # Some transactions?
+    my $remote_uri = RT::URI->new( $self->CurrentUser );
+    $remote_uri->FromURI( $remote_link );
+
+    my $opposite_direction = $direction eq 'Target' ? 'Base': 'Target';
+
+    unless ( $args{ 'Silent'. $direction } ) {
+        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
+            Type      => 'AddLink',
+            Field     => $LINKDIRMAP{$args{'Type'}}->{$direction},
+            NewValue  => $remote_uri->URI || $remote_link,
+            TimeTaken => 0
+        );
+        $RT::Logger->error("Couldn't create transaction: $Msg") unless $Trans;
+    }
+
+    if ( !$args{"Silent$opposite_direction"} && $remote_uri->IsLocal ) {
+        my $OtherObj = $remote_uri->Object;
+        my ( $val, $msg ) = $OtherObj->_NewTransaction(
+            Type           => 'AddLink',
+            Field          => $LINKDIRMAP{$args{'Type'}}->{$opposite_direction},
+            NewValue       => $self->URI,
+            ActivateScrips => !RT->Config->Get('LinkTransactionsRun1Scrip'),
+            TimeTaken      => 0,
+        );
+        $RT::Logger->error("Couldn't create transaction: $msg") unless $val;
+    }
+
+    return ($linkid, $TransString);
 }
 
 =head2 _DeleteLink
 
-Delete a link. takes a paramhash of Base, Target and Type.
-Either Base or Target must be null. The null value will 
-be replaced with this ticket\'s id
+Takes a paramhash of Type and one of Base or Target. Removes that link from this object.
+
+If Silent is true then no transactions will be recorded.  You can individually
+control transactions on both base and target and with SilentBase and
+SilentTarget respectively. By default both transactions are created.
+
+Returns a tuple of (status flag, message).
 
 =cut 
 
 sub _DeleteLink {
     my $self = shift;
     my %args = (
-        Base   => undef,
-        Target => undef,
-        Type   => undef,
+        Base         => undef,
+        Target       => undef,
+        Type         => undef,
+        Silent       => undef,
+        SilentBase   => undef,
+        SilentTarget => undef,
         @_
     );
 
@@ -1388,24 +1433,56 @@ sub _DeleteLink {
         Target => $args{'Target'}
     );
 
-    # it's a real link.
-    if ( $link->id ) {
-        my $basetext = $self->FormatLink(Object   => $link->BaseObj,
-                                         FallBack => $args{Base});
-        my $targettext = $self->FormatLink(Object   => $link->TargetObj,
-                                           FallBack => $args{Target});
-        my $typetext = $self->FormatType(Type => $args{Type});
-        my $linkid = $link->id;
-        $link->Delete();
-        my $TransString = "$basetext no longer $typetext $targettext.";
-        return ( 1, $TransString);
-    }
-
-    #if it's not a link we can find
-    else {
+    unless ($link->id) {
         $RT::Logger->debug("Couldn't find that link");
         return ( 0, $self->loc("Link not found") );
     }
+
+    my $basetext = $self->FormatLink(Object   => $link->BaseObj,
+                                     FallBack => $args{Base});
+    my $targettext = $self->FormatLink(Object   => $link->TargetObj,
+                                       FallBack => $args{Target});
+    my $typetext = $self->FormatType(Type => $args{Type});
+    my $TransString = "$basetext no longer $typetext $targettext.";
+
+    my ($ok, $msg) = $link->Delete();
+    unless ($ok) {
+        RT->Logger->error("Link could not be deleted: $msg");
+        return ( 0, $self->loc("Link could not be deleted: [_1]", $msg) );
+    }
+
+    # No transactions for you!
+    return (1, $TransString) if $args{'Silent'};
+
+    # Some transactions?
+    my $remote_uri = RT::URI->new( $self->CurrentUser );
+    $remote_uri->FromURI( $remote_link );
+
+    my $opposite_direction = $direction eq 'Target' ? 'Base': 'Target';
+
+    unless ( $args{ 'Silent'. $direction } ) {
+        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
+            Type      => 'DeleteLink',
+            Field     => $LINKDIRMAP{$args{'Type'}}->{$direction},
+            OldValue  => $remote_uri->URI || $remote_link,
+            TimeTaken => 0
+        );
+        $RT::Logger->error("Couldn't create transaction: $Msg") unless $Trans;
+    }
+
+    if ( !$args{"Silent$opposite_direction"} && $remote_uri->IsLocal ) {
+        my $OtherObj = $remote_uri->Object;
+        my ( $val, $msg ) = $OtherObj->_NewTransaction(
+            Type           => 'DeleteLink',
+            Field          => $LINKDIRMAP{$args{'Type'}}->{$opposite_direction},
+            OldValue       => $self->URI,
+            ActivateScrips => !RT->Config->Get('LinkTransactionsRun1Scrip'),
+            TimeTaken      => 0,
+        );
+        $RT::Logger->error("Couldn't create transaction: $msg") unless $val;
+    }
+
+    return (1, $TransString);
 }
 
 =head2 _NewTransaction  PARAMHASH
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index cf6ac40..ae93816 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -2413,14 +2413,10 @@ sub _Links {
 
 =head2 DeleteLink
 
-Delete a link. takes a paramhash of Base, Target, Type, Silent,
-SilentBase and SilentTarget. Either Base or Target must be null.
-The null value will be replaced with this ticket\'s id.
+Takes a paramhash of Type and one of Base or Target. Removes that link from this ticket.
 
-If Silent is true then no transaction would be recorded, in other
-case you can control creation of transactions on both base and
-target with SilentBase and SilentTarget respectively. By default
-both transactions are created.
+Refer to L<RT::Record/_DeleteLink> for full documentation.  This method
+implements permission checks before calling into L<RT::Record>.
 
 =cut 
 
@@ -2429,10 +2425,6 @@ sub DeleteLink {
     my %args = (
         Base   => undef,
         Target => undef,
-        Type   => undef,
-        Silent => undef,
-        SilentBase   => undef,
-        SilentTarget => undef,
         @_
     );
 
@@ -2461,61 +2453,15 @@ sub DeleteLink {
         return ( 0, $self->loc("Permission Denied") );
     }
 
-    my ($val, $Msg) = $self->SUPER::_DeleteLink(%args);
-    return ( 0, $Msg ) unless $val;
-
-    return ( $val, $Msg ) if $args{'Silent'};
-
-    my ($direction, $remote_link);
-
-    if ( $args{'Base'} ) {
-        $remote_link = $args{'Base'};
-        $direction = 'Target';
-    }
-    elsif ( $args{'Target'} ) {
-        $remote_link = $args{'Target'};
-        $direction = 'Base';
-    } 
-
-    my $remote_uri = RT::URI->new( $self->CurrentUser );
-    $remote_uri->FromURI( $remote_link );
-
-    unless ( $args{ 'Silent'. $direction } ) {
-        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
-            Type      => 'DeleteLink',
-            Field     => $LINKDIRMAP{$args{'Type'}}->{$direction},
-            OldValue  => $remote_uri->URI || $remote_link,
-            TimeTaken => 0
-        );
-        $RT::Logger->error("Couldn't create transaction: $Msg") unless $Trans;
-    }
-
-    if ( !$args{ 'Silent'. ( $direction eq 'Target'? 'Base': 'Target' ) } && $remote_uri->IsLocal ) {
-        my $OtherObj = $remote_uri->Object;
-        my ( $val, $Msg ) = $OtherObj->_NewTransaction(
-            Type           => 'DeleteLink',
-            Field          => $direction eq 'Target' ? $LINKDIRMAP{$args{'Type'}}->{Base}
-                                            : $LINKDIRMAP{$args{'Type'}}->{Target},
-            OldValue       => $self->URI,
-            ActivateScrips => !RT->Config->Get('LinkTransactionsRun1Scrip'),
-            TimeTaken      => 0,
-        );
-        $RT::Logger->error("Couldn't create transaction: $Msg") unless $val;
-    }
-
-    return ( $val, $Msg );
+    return $self->_DeleteLink(%args);
 }
 
-
-
 =head2 AddLink
 
 Takes a paramhash of Type and one of Base or Target. Adds that link to this ticket.
 
-If Silent is true then no transaction would be recorded, in other
-case you can control creation of transactions on both base and
-target with SilentBase and SilentTarget respectively. By default
-both transactions are created.
+Refer to L<RT::Record/_AddLink> for full documentation.  This method implements
+permissions and ticket validity checks before calling into L<RT::Record>.
 
 =cut
 
@@ -2580,67 +2526,6 @@ sub __GetTicketFromURI {
     return (1, 'Found ticket', $obj);
 }
 
-=head2 _AddLink  
-
-Private non-acled variant of AddLink so that links can be added during create.
-
-=cut
-
-sub _AddLink {
-    my $self = shift;
-    my %args = ( Target       => '',
-                 Base         => '',
-                 Type         => '',
-                 Silent       => undef,
-                 SilentBase   => undef,
-                 SilentTarget => undef,
-                 @_ );
-
-    my ($val, $msg, $exist) = $self->SUPER::_AddLink(%args);
-    return ($val, $msg) if !$val || $exist;
-    return ($val, $msg) if $args{'Silent'};
-
-    my ($direction, $remote_link);
-    if ( $args{'Target'} ) {
-        $remote_link  = $args{'Target'};
-        $direction    = 'Base';
-    } elsif ( $args{'Base'} ) {
-        $remote_link  = $args{'Base'};
-        $direction    = 'Target';
-    }
-
-    my $remote_uri = RT::URI->new( $self->CurrentUser );
-    $remote_uri->FromURI( $remote_link );
-
-    unless ( $args{ 'Silent'. $direction } ) {
-        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
-            Type      => 'AddLink',
-            Field     => $LINKDIRMAP{$args{'Type'}}->{$direction},
-            NewValue  =>  $remote_uri->URI || $remote_link,
-            TimeTaken => 0
-        );
-        $RT::Logger->error("Couldn't create transaction: $Msg") unless $Trans;
-    }
-
-    if ( !$args{ 'Silent'. ( $direction eq 'Target'? 'Base': 'Target' ) } && $remote_uri->IsLocal ) {
-        my $OtherObj = $remote_uri->Object;
-        my ( $val, $msg ) = $OtherObj->_NewTransaction(
-            Type           => 'AddLink',
-            Field          => $direction eq 'Target' ? $LINKDIRMAP{$args{'Type'}}->{Base}
-                                            : $LINKDIRMAP{$args{'Type'}}->{Target},
-            NewValue       => $self->URI,
-            ActivateScrips => !RT->Config->Get('LinkTransactionsRun1Scrip'),
-            TimeTaken      => 0,
-        );
-        $RT::Logger->error("Couldn't create transaction: $msg") unless $val;
-    }
-
-    return ( $val, $msg );
-}
-
-
-
-
 =head2 MergeInto
 
 MergeInto take the id of the ticket to merge this ticket into.

commit 4effe0cca3dc163e2d4444432245c48db6354f10
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Fri Aug 17 13:16:03 2012 -0700

    Refactor our link type and direction maps into RT::Link
    
    A single definition is much cleaner and easier to maintain than
    duplicates scattered among the classes or pointers into RT::Ticket.
    
    Any existing non-core code which needs the maps will need to be updated
    to point to RT::Link.

diff --git a/docs/UPGRADING-4.2 b/docs/UPGRADING-4.2
index 66af083..ed52460 100644
--- a/docs/UPGRADING-4.2
+++ b/docs/UPGRADING-4.2
@@ -4,3 +4,9 @@ UPGRADING FROM RT 4.0.0 and greater
   describes what the log level controls.  Setting $LogToScreen will still work,
   but an informational notice will be issued on server start telling you about
   the rename.  To avoid this you should set $LogToSTDERR instead.
+
+* The link direction and type maps are consolidated into RT::Link.  If you
+  wrote local customizations or extensions utilizing %RT::Ticket::LINKDIRMAP,
+  %RT::Ticket::LINKTYPEMAP, RT::Ticket->LINKDIRMAP, RT::Ticket->LINKTYPEMAP, or
+  %RT::Record::LINKDIRMAP, you will need to switch to %RT::Link::DIRMAP and
+  %RT::Link::TYPEMAP.
diff --git a/lib/RT/Action/CreateTickets.pm b/lib/RT/Action/CreateTickets.pm
index 298f7e9..38028cb 100644
--- a/lib/RT/Action/CreateTickets.pm
+++ b/lib/RT/Action/CreateTickets.pm
@@ -53,6 +53,7 @@ use strict;
 use warnings;
 
 use MIME::Entity;
+use RT::Link;
 
 =head1 NAME
 
@@ -253,47 +254,6 @@ perl(1).
 
 =cut
 
-my %LINKTYPEMAP = (
-    MemberOf => {
-        Type => 'MemberOf',
-        Mode => 'Target',
-    },
-    Parents => {
-        Type => 'MemberOf',
-        Mode => 'Target',
-    },
-    Members => {
-        Type => 'MemberOf',
-        Mode => 'Base',
-    },
-    Children => {
-        Type => 'MemberOf',
-        Mode => 'Base',
-    },
-    HasMember => {
-        Type => 'MemberOf',
-        Mode => 'Base',
-    },
-    RefersTo => {
-        Type => 'RefersTo',
-        Mode => 'Target',
-    },
-    ReferredToBy => {
-        Type => 'RefersTo',
-        Mode => 'Base',
-    },
-    DependsOn => {
-        Type => 'DependsOn',
-        Mode => 'Target',
-    },
-    DependedOnBy => {
-        Type => 'DependsOn',
-        Mode => 'Base',
-    },
-
-);
-
-
 #Do what we need to do and send it out.
 sub Commit {
     my $self = shift;
@@ -721,7 +681,7 @@ sub ParseLines {
                 }
                 if (
                     ($tag =~ /^(requestor|cc|admincc)(group)?$/i
-                        or grep {lc $_ eq $tag} keys %LINKTYPEMAP)
+                        or grep {lc $_ eq $tag} keys %RT::Link::TYPEMAP)
                     and $args{$tag} =~ /,/
                 ) {
                     $args{$tag} = [ split /,\s*/, $args{$tag} ];
@@ -1006,7 +966,7 @@ sub GetUpdateTemplate {
     $string .= "InitialPriority: " . $t->Priority . "\n";
     $string .= "FinalPriority: " . $t->FinalPriority . "\n";
 
-    foreach my $type ( sort keys %LINKTYPEMAP ) {
+    foreach my $type ( sort keys %RT::Link::TYPEMAP ) {
 
         # don't display duplicates
         if (   $type eq "HasMember"
@@ -1017,8 +977,8 @@ sub GetUpdateTemplate {
         }
         $string .= "$type: ";
 
-        my $mode   = $LINKTYPEMAP{$type}->{Mode};
-        my $method = $LINKTYPEMAP{$type}->{Type};
+        my $mode   = $RT::Link::TYPEMAP{$type}->{Mode};
+        my $method = $RT::Link::TYPEMAP{$type}->{Type};
 
         my $links = '';
         while ( my $link = $t->$method->Next ) {
@@ -1084,7 +1044,7 @@ sub GetCreateTemplate {
     $string .= "InitialPriority: \n";
     $string .= "FinalPriority: \n";
 
-    foreach my $type ( keys %LINKTYPEMAP ) {
+    foreach my $type ( keys %RT::Link::TYPEMAP ) {
 
         # don't display duplicates
         if (   $type eq "HasMember"
@@ -1214,7 +1174,7 @@ sub PostProcess {
         $RT::Logger->debug( "Handling links for " . $ticket->Id );
         my %args = %{ shift(@$links) };
 
-        foreach my $type ( keys %LINKTYPEMAP ) {
+        foreach my $type ( keys %RT::Link::TYPEMAP ) {
             next unless ( defined $args{$type} );
             foreach my $link (
                 ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) )
@@ -1241,8 +1201,8 @@ sub PostProcess {
                 }
 
                 my ( $wval, $wmsg ) = $ticket->AddLink(
-                    Type => $LINKTYPEMAP{$type}->{'Type'},
-                    $LINKTYPEMAP{$type}->{'Mode'} => $link,
+                    Type => $RT::Link::TYPEMAP{$type}->{'Type'},
+                    $RT::Link::TYPEMAP{$type}->{'Mode'} => $link,
                     Silent                        => 1
                 );
 
diff --git a/lib/RT/Link.pm b/lib/RT/Link.pm
index b26f564..f1d0139 100644
--- a/lib/RT/Link.pm
+++ b/lib/RT/Link.pm
@@ -79,6 +79,26 @@ sub Table {'Links'}
 use Carp;
 use RT::URI;
 
+# Helper tables for links mapping to make it easier
+# to build and parse links between objects.
+our %TYPEMAP = (
+    MemberOf        => { Type => 'MemberOf',    Mode => 'Target' },
+    Parents         => { Type => 'MemberOf',    Mode => 'Target' },
+    Members         => { Type => 'MemberOf',    Mode => 'Base'   },
+    Children        => { Type => 'MemberOf',    Mode => 'Base'   },
+    HasMember       => { Type => 'MemberOf',    Mode => 'Base'   },
+    RefersTo        => { Type => 'RefersTo',    Mode => 'Target' },
+    ReferredToBy    => { Type => 'RefersTo',    Mode => 'Base'   },
+    DependsOn       => { Type => 'DependsOn',   Mode => 'Target' },
+    DependedOnBy    => { Type => 'DependsOn',   Mode => 'Base'   },
+    MergedInto      => { Type => 'MergedInto',  Mode => 'Target' },
+);
+our %DIRMAP = (
+    MemberOf    => { Base => 'MemberOf',    Target => 'HasMember'    },
+    RefersTo    => { Base => 'RefersTo',    Target => 'ReferredToBy' },
+    DependsOn   => { Base => 'DependsOn',   Target => 'DependedOnBy' },
+    MergedInto  => { Base => 'MergedInto',  Target => 'MergedInto'   },
+);
 
 
 =head2 Create PARAMHASH
diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm
index 6e6e87d..3b524f8 100644
--- a/lib/RT/Record.pm
+++ b/lib/RT/Record.pm
@@ -70,6 +70,7 @@ use warnings;
 use RT::Date;
 use RT::User;
 use RT::Attributes;
+use RT::Link;
 use Encode qw();
 
 our $_TABLE_ATTR = { };
@@ -820,23 +821,6 @@ sub _DecodeLOB {
         return ($Content);
 }
 
-# A helper table for links mapping to make it easier
-# to build and parse links between tickets
-
-use vars '%LINKDIRMAP';
-
-%LINKDIRMAP = (
-    MemberOf => { Base => 'MemberOf',
-                  Target => 'HasMember', },
-    RefersTo => { Base => 'RefersTo',
-                Target => 'ReferredToBy', },
-    DependsOn => { Base => 'DependsOn',
-                   Target => 'DependedOnBy', },
-    MergedInto => { Base => 'MergedInto',
-                   Target => 'MergedInto', },
-
-);
-
 =head2 Update  ARGSHASH
 
 Updates fields on an object for you using the proper Set methods,
@@ -1352,7 +1336,7 @@ sub _AddLink {
     unless ( $args{ 'Silent'. $direction } ) {
         my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
             Type      => 'AddLink',
-            Field     => $LINKDIRMAP{$args{'Type'}}->{$direction},
+            Field     => $RT::Link::DIRMAP{$args{'Type'}}->{$direction},
             NewValue  => $remote_uri->URI || $remote_link,
             TimeTaken => 0
         );
@@ -1363,7 +1347,7 @@ sub _AddLink {
         my $OtherObj = $remote_uri->Object;
         my ( $val, $msg ) = $OtherObj->_NewTransaction(
             Type           => 'AddLink',
-            Field          => $LINKDIRMAP{$args{'Type'}}->{$opposite_direction},
+            Field          => $RT::Link::DIRMAP{$args{'Type'}}->{$opposite_direction},
             NewValue       => $self->URI,
             ActivateScrips => !RT->Config->Get('LinkTransactionsRun1Scrip'),
             TimeTaken      => 0,
@@ -1463,7 +1447,7 @@ sub _DeleteLink {
     unless ( $args{ 'Silent'. $direction } ) {
         my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
             Type      => 'DeleteLink',
-            Field     => $LINKDIRMAP{$args{'Type'}}->{$direction},
+            Field     => $RT::Link::DIRMAP{$args{'Type'}}->{$direction},
             OldValue  => $remote_uri->URI || $remote_link,
             TimeTaken => 0
         );
@@ -1474,7 +1458,7 @@ sub _DeleteLink {
         my $OtherObj = $remote_uri->Object;
         my ( $val, $msg ) = $OtherObj->_NewTransaction(
             Type           => 'DeleteLink',
-            Field          => $LINKDIRMAP{$args{'Type'}}->{$opposite_direction},
+            Field          => $RT::Link::DIRMAP{$args{'Type'}}->{$opposite_direction},
             OldValue       => $self->URI,
             ActivateScrips => !RT->Config->Get('LinkTransactionsRun1Scrip'),
             TimeTaken      => 0,
diff --git a/lib/RT/Shredder/Link.pm b/lib/RT/Shredder/Link.pm
index 94beb86..e47259c 100644
--- a/lib/RT/Shredder/Link.pm
+++ b/lib/RT/Shredder/Link.pm
@@ -72,7 +72,7 @@ sub __DependsOn
     my $list = [];
 
 # AddLink transactions
-    my $map = RT::Ticket->LINKTYPEMAP;
+    my $map = { %RT::Link::TYPEMAP };
     my $link_meta = $map->{ $self->Type };
     unless ( $link_meta && $link_meta->{'Mode'} && $link_meta->{'Type'} ) {
         RT::Shredder::Exception->throw( 'Wrong link link_meta, no record for '. $self->Type );
diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index d9c43ab..4b90855 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -722,7 +722,7 @@ sub create_tickets {
     while ( @data ) {
         my %args = %{ shift @data };
         $args{$_} = $res[ $args{$_} ]->id foreach
-            grep $args{ $_ }, keys %RT::Ticket::LINKTYPEMAP;
+            grep $args{ $_ }, keys %RT::Link::TYPEMAP;
         push @res, $self->create_ticket( %$defaults, %args );
     }
     return @res;
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index ae93816..18c22cb 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -72,6 +72,7 @@ use warnings;
 use RT::Queue;
 use RT::User;
 use RT::Record;
+use RT::Link;
 use RT::Links;
 use RT::Date;
 use RT::CustomFields;
@@ -83,54 +84,6 @@ use RT::URI;
 use MIME::Entity;
 use Devel::GlobalDestruction;
 
-
-# A helper table for links mapping to make it easier
-# to build and parse links between tickets
-
-our %LINKTYPEMAP = (
-    MemberOf => { Type => 'MemberOf',
-                  Mode => 'Target', },
-    Parents => { Type => 'MemberOf',
-         Mode => 'Target', },
-    Members => { Type => 'MemberOf',
-                 Mode => 'Base', },
-    Children => { Type => 'MemberOf',
-          Mode => 'Base', },
-    HasMember => { Type => 'MemberOf',
-                   Mode => 'Base', },
-    RefersTo => { Type => 'RefersTo',
-                  Mode => 'Target', },
-    ReferredToBy => { Type => 'RefersTo',
-                      Mode => 'Base', },
-    DependsOn => { Type => 'DependsOn',
-                   Mode => 'Target', },
-    DependedOnBy => { Type => 'DependsOn',
-                      Mode => 'Base', },
-    MergedInto => { Type => 'MergedInto',
-                   Mode => 'Target', },
-
-);
-
-
-# A helper table for links mapping to make it easier
-# to build and parse links between tickets
-
-our %LINKDIRMAP = (
-    MemberOf => { Base => 'MemberOf',
-                  Target => 'HasMember', },
-    RefersTo => { Base => 'RefersTo',
-                Target => 'ReferredToBy', },
-    DependsOn => { Base => 'DependsOn',
-                   Target => 'DependedOnBy', },
-    MergedInto => { Base => 'MergedInto',
-                   Target => 'MergedInto', },
-
-);
-
-
-sub LINKTYPEMAP   { return \%LINKTYPEMAP   }
-sub LINKDIRMAP   { return \%LINKDIRMAP   }
-
 our %MERGE_CACHE = (
     effective => {},
     merged => {},
@@ -608,7 +561,7 @@ sub Create {
     #
     # //RUZ
 
-    foreach my $type ( keys %LINKTYPEMAP ) {
+    foreach my $type ( keys %RT::Link::TYPEMAP ) {
         next unless ( defined $args{$type} );
         foreach my $link (
             ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) )
@@ -635,10 +588,10 @@ sub Create {
             }
 
             my ( $wval, $wmsg ) = $self->_AddLink(
-                Type                          => $LINKTYPEMAP{$type}->{'Type'},
-                $LINKTYPEMAP{$type}->{'Mode'} => $link,
+                Type                          => $RT::Link::TYPEMAP{$type}->{'Type'},
+                $RT::Link::TYPEMAP{$type}->{'Mode'} => $link,
                 Silent                        => !$args{'_RecordTransaction'} || $self->Type eq 'reminder',
-                'Silent'. ( $LINKTYPEMAP{$type}->{'Mode'} eq 'Base'? 'Target': 'Base' )
+                'Silent'. ( $RT::Link::TYPEMAP{$type}->{'Mode'} eq 'Base'? 'Target': 'Base' )
                                               => 1,
             );
 
diff --git a/share/html/Elements/RT__Ticket/ColumnMap b/share/html/Elements/RT__Ticket/ColumnMap
index 31f7cd2..fcecb01 100644
--- a/share/html/Elements/RT__Ticket/ColumnMap
+++ b/share/html/Elements/RT__Ticket/ColumnMap
@@ -57,8 +57,8 @@ my $COLUMN_MAP;
 my $LinkCallback = sub {
     my $method = shift;
 
-    my $mode            = $RT::Ticket::LINKTYPEMAP{$method}{Mode};
-    my $type            = $RT::Ticket::LINKTYPEMAP{$method}{Type};
+    my $mode            = $RT::Link::TYPEMAP{$method}{Mode};
+    my $type            = $RT::Link::TYPEMAP{$method}{Type};
     my $other_mode      = ($mode eq "Target" ? "Base" : "Target");
     my $mode_uri        = $mode.'URI';
     my $local_type      = 'Local'.$mode;
@@ -291,7 +291,7 @@ $COLUMN_MAP = {
     # Everything from LINKTYPEMAP
     (map {
         $_ => { value => $LinkCallback->( $_ ) }
-    } keys %RT::Ticket::LINKTYPEMAP),
+    } keys %RT::Link::TYPEMAP),
 
     '_CLASS' => {
         value => sub { return $_[1] % 2 ? 'oddline' : 'evenline' }
diff --git a/share/html/Elements/ShowLinks b/share/html/Elements/ShowLinks
index 61628de..9a9536c 100755
--- a/share/html/Elements/ShowLinks
+++ b/share/html/Elements/ShowLinks
@@ -156,8 +156,8 @@ my $can_create = $Ticket->QueueObj->CurrentUserHasRight('CreateTicket');
 
 for my $relation (
     qw(RefersTo ReferredToBy)) {
-    my $mode  = $RT::Ticket::LINKTYPEMAP{$relation}->{Mode};
-    my $type  = $RT::Ticket::LINKTYPEMAP{$relation}->{Type};
+    my $mode  = $RT::Link::TYPEMAP{$relation}->{Mode};
+    my $type  = $RT::Link::TYPEMAP{$relation}->{Type};
     my $other = "Local" . $mode;
     my $field = $mode eq 'Base' ? 'new-' . $type : $type . '-new';
     $clone->{$field} 
@@ -167,8 +167,8 @@ for my $relation (
 }
 
 for my $relation ( qw(MemberOf Members DependsOn DependedOnBy)) {
-    my $mode  = $RT::Ticket::LINKTYPEMAP{$relation}->{Mode};
-    my $type  = $RT::Ticket::LINKTYPEMAP{$relation}->{Type};
+    my $mode  = $RT::Link::TYPEMAP{$relation}->{Mode};
+    my $type  = $RT::Link::TYPEMAP{$relation}->{Type};
     my $field = $mode eq 'Base' ? 'new-' . $type : $type . '-new';
     $clone->{$field} = $path . "&$field=$id";
 }
diff --git a/share/html/Elements/ShowRelationLabel b/share/html/Elements/ShowRelationLabel
index 9e6ea97..cf872c4 100644
--- a/share/html/Elements/ShowRelationLabel
+++ b/share/html/Elements/ShowRelationLabel
@@ -47,10 +47,10 @@
 %# END BPS TAGGED BLOCK }}}
 <a href="<%$SearchURL |n %>"><%$Label%></a>
 <%INIT>
-my $typemap = RT::Ticket->LINKTYPEMAP->{$Relation};
+my $typemap = $RT::Link::TYPEMAP{$Relation};
 my $search_mode = $typemap->{Mode};
 my $search_type = $typemap->{Type};
-my $search_relation = RT::Ticket->LINKDIRMAP->{$search_type}{$search_mode};
+my $search_relation = $RT::Link::DIRMAP{$search_type}->{$search_mode};
 
 my $Query = $search_relation . ' = ' . $id;
 my $SearchURL = RT->Config->Get('WebPath') . '/Search/Results.html?' . $m->comp('/Elements/QueryString', Query => $Query);

-----------------------------------------------------------------------


More information about the Rt-commit mailing list