[Rt-commit] rt branch, 4.2/link-api-refactoring, created. rt-4.0.6-453-g76a9d8d
Thomas Sibley
trs at bestpractical.com
Thu Oct 18 21:16:55 EDT 2012
The branch, 4.2/link-api-refactoring has been created
at 76a9d8dc934c014c86279b1c3b716a9b40609df7 (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);
commit 5b833f649cd754e27bba672891d4ee2635e5d7ed
Author: Thomas Sibley <trs at bestpractical.com>
Date: Fri Aug 17 16:04:21 2012 -0700
Remove hardcoded duplicate types from CreateTickets.pm
Provides a convenience method, RT::Link->DisplayTypes, for extracting
the canonical directional link types from the (for now) public RT::Link
data structures.
The link data structures sorely want to be refactored even harder into
an API.
diff --git a/lib/RT/Action/CreateTickets.pm b/lib/RT/Action/CreateTickets.pm
index 38028cb..d4d0d51 100644
--- a/lib/RT/Action/CreateTickets.pm
+++ b/lib/RT/Action/CreateTickets.pm
@@ -966,15 +966,7 @@ sub GetUpdateTemplate {
$string .= "InitialPriority: " . $t->Priority . "\n";
$string .= "FinalPriority: " . $t->FinalPriority . "\n";
- foreach my $type ( sort keys %RT::Link::TYPEMAP ) {
-
- # don't display duplicates
- if ( $type eq "HasMember"
- || $type eq "Members"
- || $type eq "MemberOf" )
- {
- next;
- }
+ foreach my $type ( RT::Link->DisplayTypes ) {
$string .= "$type: ";
my $mode = $RT::Link::TYPEMAP{$type}->{Mode};
@@ -1044,15 +1036,7 @@ sub GetCreateTemplate {
$string .= "InitialPriority: \n";
$string .= "FinalPriority: \n";
- foreach my $type ( keys %RT::Link::TYPEMAP ) {
-
- # don't display duplicates
- if ( $type eq "HasMember"
- || $type eq 'Members'
- || $type eq 'MemberOf' )
- {
- next;
- }
+ foreach my $type ( RT::Link->DisplayTypes ) {
$string .= "$type: \n";
}
return $string;
diff --git a/lib/RT/Link.pm b/lib/RT/Link.pm
index f1d0139..f9b2bd6 100644
--- a/lib/RT/Link.pm
+++ b/lib/RT/Link.pm
@@ -59,10 +59,6 @@
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
@@ -78,20 +74,22 @@ use base 'RT::Record';
sub Table {'Links'}
use Carp;
use RT::URI;
+use List::Util 'first';
+use List::MoreUtils 'uniq';
# 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' },
+ MemberOf => { Type => 'MemberOf', Mode => 'Target', Display => 0 },
+ Parents => { Type => 'MemberOf', Mode => 'Target', Display => 1 },
+ Members => { Type => 'MemberOf', Mode => 'Base', Display => 0 },
+ Children => { Type => 'MemberOf', Mode => 'Base', Display => 1 },
+ HasMember => { Type => 'MemberOf', Mode => 'Base', Display => 0 },
+ RefersTo => { Type => 'RefersTo', Mode => 'Target', Display => 1 },
+ ReferredToBy => { Type => 'RefersTo', Mode => 'Base', Display => 1 },
+ DependsOn => { Type => 'DependsOn', Mode => 'Target', Display => 1 },
+ DependedOnBy => { Type => 'DependsOn', Mode => 'Base', Display => 1 },
+ MergedInto => { Type => 'MergedInto', Mode => 'Target', Display => 1 },
);
our %DIRMAP = (
MemberOf => { Base => 'MemberOf', Target => 'HasMember' },
@@ -100,6 +98,40 @@ our %DIRMAP = (
MergedInto => { Base => 'MergedInto', Target => 'MergedInto' },
);
+__PACKAGE__->_BuildDisplayAs;
+
+my %DISPLAY_AS;
+sub _BuildDisplayAs {
+ %DISPLAY_AS = ();
+ foreach my $in_db ( uniq map { $_->{Type} } values %TYPEMAP ) {
+ foreach my $mode (qw(Base Target)) {
+ $DISPLAY_AS{$in_db}{$mode} = first {
+ $TYPEMAP{$_}{Display}
+ && $TYPEMAP{$_}{Type} eq $in_db
+ && $TYPEMAP{$_}{Mode} eq $mode
+ } keys %TYPEMAP;
+ }
+ }
+}
+
+=head1 CLASS METHODS
+
+=head2 DisplayTypes
+
+Returns a list of the standard link Types for display, including directional
+variants but not aliases.
+
+=cut
+
+sub DisplayTypes {
+ sort { $a cmp $b }
+ uniq
+ grep { defined }
+ map { values %$_ }
+ values %DISPLAY_AS
+}
+
+=head1 METHODS
=head2 Create PARAMHASH
@@ -302,7 +334,6 @@ sub BaseObj {
return $self->BaseURI->Object;
}
-
=head2 id
Returns the current value of id.
commit 417945f7429832f4543cc0a3df9bb5721ffccf8d
Author: Thomas Sibley <trs at bestpractical.com>
Date: Fri Aug 17 15:43:21 2012 -0700
Support singular link types for ticket creation
The singular forms are more intuitive than the plurals when dealing with
a single link.
diff --git a/lib/RT/Link.pm b/lib/RT/Link.pm
index f9b2bd6..0f9fa9f 100644
--- a/lib/RT/Link.pm
+++ b/lib/RT/Link.pm
@@ -82,8 +82,11 @@ use List::MoreUtils 'uniq';
our %TYPEMAP = (
MemberOf => { Type => 'MemberOf', Mode => 'Target', Display => 0 },
Parents => { Type => 'MemberOf', Mode => 'Target', Display => 1 },
+ Parent => { Type => 'MemberOf', Mode => 'Target', Display => 0 },
Members => { Type => 'MemberOf', Mode => 'Base', Display => 0 },
+ Member => { Type => 'MemberOf', Mode => 'Base', Display => 0 },
Children => { Type => 'MemberOf', Mode => 'Base', Display => 1 },
+ Child => { Type => 'MemberOf', Mode => 'Base', Display => 0 },
HasMember => { Type => 'MemberOf', Mode => 'Base', Display => 0 },
RefersTo => { Type => 'RefersTo', Mode => 'Target', Display => 1 },
ReferredToBy => { Type => 'RefersTo', Mode => 'Base', Display => 1 },
commit eae7599d2282029137e62099b9e9c453ff715274
Author: Thomas Sibley <trs at bestpractical.com>
Date: Thu Oct 18 17:16:51 2012 -0700
Use our link maps instead of hardcoding link type pairs
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 8a01217..d42c3a3 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1687,18 +1687,14 @@ sub CreateTicket {
}
# turn new link lists into arrays, and pass in the proper arguments
- my %map = (
- 'new-DependsOn' => 'DependsOn',
- 'DependsOn-new' => 'DependedOnBy',
- 'new-MemberOf' => 'Parents',
- 'MemberOf-new' => 'Children',
- 'new-RefersTo' => 'RefersTo',
- 'RefersTo-new' => 'ReferredToBy',
- );
- foreach my $key ( keys %map ) {
- next unless $ARGS{$key};
- $create_args{ $map{$key} } = [ grep $_, split ' ', $ARGS{$key} ];
-
+ foreach my $type ( keys %RT::Link::DIRMAP ) {
+ for ([Base => "new-$type"], [Target => "$type-new"]) {
+ my ($direction, $key) = @$_;
+ next unless $ARGS{$key};
+ $create_args{ $RT::Link::DIRMAP{$type}->{$direction} } = [
+ grep $_, split ' ', $ARGS{$key}
+ ];
+ }
}
my ( $id, $Trans, $ErrMsg ) = $Ticket->Create(%create_args);
commit 76a9d8dc934c014c86279b1c3b716a9b40609df7
Author: Thomas Sibley <trs at bestpractical.com>
Date: Thu Oct 18 17:38:00 2012 -0700
Refactor processing %ARGS for new links during record creation
The inputs processed are generated by /Elements/EditLinks and may be
used by object types other than tickets. Refactoring into a function
lets other objects re-use the same code.
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index d42c3a3..673ce42 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1686,18 +1686,9 @@ sub CreateTicket {
}
}
- # turn new link lists into arrays, and pass in the proper arguments
- foreach my $type ( keys %RT::Link::DIRMAP ) {
- for ([Base => "new-$type"], [Target => "$type-new"]) {
- my ($direction, $key) = @$_;
- next unless $ARGS{$key};
- $create_args{ $RT::Link::DIRMAP{$type}->{$direction} } = [
- grep $_, split ' ', $ARGS{$key}
- ];
- }
- }
+ my %links = ProcessLinksForCreate( ARGSRef => \%ARGS );
- my ( $id, $Trans, $ErrMsg ) = $Ticket->Create(%create_args);
+ my ( $id, $Trans, $ErrMsg ) = $Ticket->Create(%create_args, %links);
unless ($id) {
Abort($ErrMsg);
}
@@ -2910,6 +2901,41 @@ sub ProcessRecordLinks {
return (@results);
}
+=head2 ProcessLinksForCreate
+
+Takes a hash with a single key, C<ARGSRef>, the value of which is a hashref to
+C<%ARGS>.
+
+Converts and returns submitted args in the form of C<new-LINKTYPE> and
+C<LINKTYPE-new> into their appropriate directional link types. For example,
+C<new-DependsOn> becomes C<DependsOn> and C<DependsOn-new> becomes
+C<DependedOnBy>. The incoming arg values are split on whitespace and
+normalized into arrayrefs before being returned.
+
+Primarily used by object creation pages for transforming incoming form inputs
+from F</Elements/EditLinks> into arguments appropriate for individual record
+Create methods.
+
+Returns a hashref in scalar context and a hash in list context.
+
+=cut
+
+sub ProcessLinksForCreate {
+ my %args = @_;
+ my %links;
+
+ foreach my $type ( keys %RT::Link::DIRMAP ) {
+ for ([Base => "new-$type"], [Target => "$type-new"]) {
+ my ($direction, $key) = @$_;
+ next unless $args{ARGSRef}->{$key};
+ $links{ $RT::Link::DIRMAP{$type}->{$direction} } = [
+ grep $_, split ' ', $args{ARGSRef}->{$key}
+ ];
+ }
+ }
+ return wantarray ? %links : \%links;
+}
+
=head2 _UploadedFile ( $arg );
Takes a CGI parameter name; if a file is uploaded under that name,
-----------------------------------------------------------------------
More information about the Rt-commit
mailing list