[rt-commit] [svn] r621 - in rt/branches/rt-3.1/lib/RT: . Interface

leira at fsck.com leira at fsck.com
Thu Mar 25 10:21:45 EST 2004


Author: leira
Date: Thu Mar 25 10:21:44 2004
New Revision: 621

Modified:
   rt/branches/rt-3.1/lib/RT/Attachments_Overlay.pm
   rt/branches/rt-3.1/lib/RT/Interface/Web.pm
   rt/branches/rt-3.1/lib/RT/Queue_Overlay.pm
   rt/branches/rt-3.1/lib/RT/Record_Overlay.pm
   rt/branches/rt-3.1/lib/RT/Ticket_Overlay.pm
   rt/branches/rt-3.1/lib/RT/Tickets_Overlay.pm
   rt/branches/rt-3.1/lib/RT/Tickets_Overlay_SQL.pm
   rt/branches/rt-3.1/lib/RT/Transactions_Overlay.pm
   rt/branches/rt-3.1/lib/RT/URI.pm
Log:
Move AddLink/DeleteLink to the Record object.
Support linking Queues.


Modified: rt/branches/rt-3.1/lib/RT/Attachments_Overlay.pm
==============================================================================
--- rt/branches/rt-3.1/lib/RT/Attachments_Overlay.pm	(original)
+++ rt/branches/rt-3.1/lib/RT/Attachments_Overlay.pm	Thu Mar 25 10:21:44 2004
@@ -117,12 +117,10 @@
     my $Attachment = $self->SUPER::Next();
     if ((defined($Attachment)) and (ref($Attachment))) {
 	if ($Attachment->TransactionObj->__Value('Type') =~ /^Comment/ && 
-	    ($Attachment->TransactionObj->TicketObj->QueueObj->CurrentUserHasRight('ShowTicketComments') ||
-	     	    $Attachment->TransactionObj->TicketObj->CurrentUserHasRight('ShowTicketComments'))) {
+	    $Attachment->TransactionObj->TicketObj->CurrentUserHasRight('ShowTicketComments')) {
 	    return($Attachment);
 	} elsif ($Attachment->TransactionObj->__Value('Type') !~ /^Comment/ && 
-		 ($Attachment->TransactionObj->TicketObj->QueueObj->CurrentUserHasRight('ShowTicket') ||
-		  $Attachment->TransactionObj->TicketObj->CurrentUserHasRight('ShowTicket'))) {
+		 $Attachment->TransactionObj->TicketObj->CurrentUserHasRight('ShowTicket')) {
 	    return($Attachment);
 	}
 

Modified: rt/branches/rt-3.1/lib/RT/Interface/Web.pm
==============================================================================
--- rt/branches/rt-3.1/lib/RT/Interface/Web.pm	(original)
+++ rt/branches/rt-3.1/lib/RT/Interface/Web.pm	Thu Mar 25 10:21:44 2004
@@ -1350,6 +1350,29 @@
     my $Ticket  = $args{'TicketObj'};
     my $ARGSRef = $args{'ARGSRef'};
 
+    my (@results) = ProcessRecordLinks(RecordObj => $Ticket,
+				       ARGSRef => $ARGSRef);
+
+    #Merge if we need to
+    if ( $ARGSRef->{ $Ticket->Id . "-MergeInto" } ) {
+        my ( $val, $msg ) =
+          $Ticket->MergeInto( $ARGSRef->{ $Ticket->Id . "-MergeInto" } );
+        push @results, $msg;
+    }
+
+    return (@results);
+}
+
+# }}}
+
+sub ProcessRecordLinks {
+    my %args = ( RecordObj => undef,
+                 ARGSRef   => undef,
+                 @_ );
+
+    my $Record  = $args{'RecordObj'};
+    my $ARGSRef = $args{'ARGSRef'};
+
     my (@results);
 
     # Delete links that are gone gone gone.
@@ -1361,7 +1384,7 @@
 
             push @results,
               "Trying to delete: Base: $base Target: $target  Type $type";
-            my ( $val, $msg ) = $Ticket->DeleteLink( Base   => $base,
+            my ( $val, $msg ) = $Record->DeleteLink( Base   => $base,
                                                      Type   => $type,
                                                      Target => $target );
 
@@ -1374,18 +1397,18 @@
     my @linktypes = qw( DependsOn MemberOf RefersTo );
 
     foreach my $linktype (@linktypes) {
-        if ( $ARGSRef->{ $Ticket->Id . "-$linktype" } ) {
-            for my $luri ( split ( / /, $ARGSRef->{ $Ticket->Id . "-$linktype" } ) ) {
+        if ( $ARGSRef->{ $Record->Id . "-$linktype" } ) {
+            for my $luri ( split ( / /, $ARGSRef->{ $Record->Id . "-$linktype" } ) ) {
                 $luri =~ s/\s*$//;    # Strip trailing whitespace
-                my ( $val, $msg ) = $Ticket->AddLink( Target => $luri,
+                my ( $val, $msg ) = $Record->AddLink( Target => $luri,
                                                       Type   => $linktype );
                 push @results, $msg;
             }
         }
-        if ( $ARGSRef->{ "$linktype-" . $Ticket->Id } ) {
+        if ( $ARGSRef->{ "$linktype-" . $Record->Id } ) {
 
-            for my $luri ( split ( / /, $ARGSRef->{ "$linktype-" . $Ticket->Id } ) ) {
-                my ( $val, $msg ) = $Ticket->AddLink( Base => $luri,
+            for my $luri ( split ( / /, $ARGSRef->{ "$linktype-" . $Record->Id } ) ) {
+                my ( $val, $msg ) = $Record->AddLink( Base => $luri,
                                                       Type => $linktype );
 
                 push @results, $msg;
@@ -1393,17 +1416,8 @@
         } 
     }
 
-    #Merge if we need to
-    if ( $ARGSRef->{ $Ticket->Id . "-MergeInto" } ) {
-        my ( $val, $msg ) =
-          $Ticket->MergeInto( $ARGSRef->{ $Ticket->Id . "-MergeInto" } );
-        push @results, $msg;
-    }
-
     return (@results);
 }
-
-# }}}
 
 eval "require RT::Interface::Web_Vendor";
 die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web_Vendor.pm});

Modified: rt/branches/rt-3.1/lib/RT/Queue_Overlay.pm
==============================================================================
--- rt/branches/rt-3.1/lib/RT/Queue_Overlay.pm	(original)
+++ rt/branches/rt-3.1/lib/RT/Queue_Overlay.pm	Thu Mar 25 10:21:44 2004
@@ -102,6 +102,39 @@
 }
     
 
+sub AddLink {
+    my $self = shift;
+    my %args = ( Target => '',
+                 Base   => '',
+                 Type   => '',
+                 Silent => undef,
+                 @_ );
+
+    unless ( $self->CurrentUserHasRight('ModifyQueue') ) {
+        return ( 0, $self->loc("Permission Denied") );
+    }
+
+    return $self->SUPER::_AddLink(%args);
+}
+
+sub DeleteLink {
+    my $self = shift;
+    my %args = (
+        Base   => undef,
+        Target => undef,
+        Type   => undef,
+        @_
+    );
+
+    #check acls
+    unless ( $self->CurrentUserHasRight('ModifyQueue') ) {
+        $RT::Logger->debug("No permission to delete links\n");
+        return ( 0, $self->loc('Permission Denied'))
+    }
+
+    return $self->SUPER::_DeleteLink(%args);
+}
+
 =head2 AvailableRights
 
 Returns a hash of available rights for this object. The keys are the right names and the values are a description of what the rights do

Modified: rt/branches/rt-3.1/lib/RT/Record_Overlay.pm
==============================================================================
--- rt/branches/rt-3.1/lib/RT/Record_Overlay.pm	(original)
+++ rt/branches/rt-3.1/lib/RT/Record_Overlay.pm	Thu Mar 25 10:21:44 2004
@@ -1,6 +1,24 @@
 use strict;
 no warnings qw(redefine);
 
+# {{{ LINKDIRMAP
+# A helper table for relationships 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', },
+
+);
+
 sub Update {
     my $self = shift;
 
@@ -114,6 +132,426 @@
     else {
 	# pathetic case -- SystemUser is gone.
 	return $_[0];
+    }
+}
+
+# }}}
+
+# {{{ Routines dealing with Links and Relations between tickets
+
+# {{{ Link Collections
+
+# {{{ sub Members
+
+=head2 Members
+
+  This returns an RT::Links object which references all the tickets 
+which are 'MembersOf' this ticket
+
+=cut
+
+sub Members {
+    my $self = shift;
+    return ( $self->_Links( 'Target', 'MemberOf' ) );
+}
+
+# }}}
+
+# {{{ sub MemberOf
+
+=head2 MemberOf
+
+  This returns an RT::Links object which references all the tickets that this
+ticket is a 'MemberOf'
+
+=cut
+
+sub MemberOf {
+    my $self = shift;
+    return ( $self->_Links( 'Base', 'MemberOf' ) );
+}
+
+# }}}
+
+# {{{ RefersTo
+
+=head2 RefersTo
+
+  This returns an RT::Links object which shows all references for which this ticket is a base
+
+=cut
+
+sub RefersTo {
+    my $self = shift;
+    return ( $self->_Links( 'Base', 'RefersTo' ) );
+}
+
+# }}}
+
+# {{{ ReferredToBy
+
+=head2 ReferredToBy
+
+  This returns an RT::Links object which shows all references for which this ticket is a target
+
+=cut
+
+sub ReferredToBy {
+    my $self = shift;
+    return ( $self->_Links( 'Target', 'RefersTo' ) );
+}
+
+# }}}
+
+# {{{ DependedOnBy
+
+=head2 DependedOnBy
+
+  This returns an RT::Links object which references all the tickets that depend on this one
+
+=cut
+
+sub DependedOnBy {
+    my $self = shift;
+    return ( $self->_Links( 'Target', 'DependsOn' ) );
+}
+
+# }}}
+
+
+
+=head2 HasUnresolvedDependencies
+
+  Takes a paramhash of Type (default to '__any').  Returns true if
+$self->UnresolvedDependencies returns an object with one or more members
+of that type.  Returns false otherwise
+
+
+=begin testing
+
+my $t1 = RT::Ticket->new($RT::SystemUser);
+my ($id, $trans, $msg) = $t1->Create(Subject => 'DepTest1', Queue => 'general');
+ok($id, "Created dep test 1 - $msg");
+
+my $t2 = RT::Ticket->new($RT::SystemUser);
+my ($id2, $trans, $msg2) = $t2->Create(Subject => 'DepTest2', Queue => 'general');
+ok($id2, "Created dep test 2 - $msg2");
+my $t3 = RT::Ticket->new($RT::SystemUser);
+my ($id3, $trans, $msg3) = $t3->Create(Subject => 'DepTest3', Queue => 'general', Type => 'approval');
+ok($id3, "Created dep test 3 - $msg3");
+my ($addid, $addmsg);
+ok (($addid, $addmsg) =$t1->AddLink( Type => 'DependsOn', Target => $t2->id));
+ok ($addid, $addmsg);
+ok (($addid, $addmsg) =$t1->AddLink( Type => 'DependsOn', Target => $t3->id));
+
+ok ($addid, $addmsg);
+ok ($t1->HasUnresolvedDependencies, "Ticket ".$t1->Id." has unresolved deps");
+ok (!$t1->HasUnresolvedDependencies( Type => 'blah' ), "Ticket ".$t1->Id." has no unresolved blahs");
+ok ($t1->HasUnresolvedDependencies( Type => 'approval' ), "Ticket ".$t1->Id." has unresolved approvals");
+ok (!$t2->HasUnresolvedDependencies, "Ticket ".$t2->Id." has no unresolved deps");
+;
+
+my ($rid, $rmsg)= $t1->Resolve();
+ok(!$rid, $rmsg);
+ok($t2->Resolve);
+($rid, $rmsg)= $t1->Resolve();
+ok(!$rid, $rmsg);
+ok($t3->Resolve);
+($rid, $rmsg)= $t1->Resolve();
+ok($rid, $rmsg);
+
+
+=end testing
+
+=cut
+
+sub HasUnresolvedDependencies {
+    my $self = shift;
+    my %args = (
+        Type   => undef,
+        @_
+    );
+
+    my $deps = $self->UnresolvedDependencies;
+
+    if ($args{Type}) {
+        $deps->Limit( FIELD => 'Type', 
+              OPERATOR => '=',
+              VALUE => $args{Type}); 
+    }
+    else {
+	    $deps->IgnoreType;
+    }
+
+    if ($deps->Count > 0) {
+        return 1;
+    }
+    else {
+        return (undef);
+    }
+}
+
+
+# {{{ UnresolvedDependencies 
+
+=head2 UnresolvedDependencies
+
+Returns an RT::Tickets object of tickets which this ticket depends on
+and which have a status of new, open or stalled. (That list comes from
+RT::Queue->ActiveStatusArray
+
+=cut
+
+
+sub UnresolvedDependencies {
+    my $self = shift;
+    my $deps = RT::Tickets->new($self->CurrentUser);
+
+    my @live_statuses = RT::Queue->ActiveStatusArray();
+    foreach my $status (@live_statuses) {
+        $deps->LimitStatus(VALUE => $status);
+    }
+    $deps->LimitDependedOnBy($self->Id);
+
+    return($deps);
+
+}
+
+# }}}
+
+# {{{ AllDependedOnBy
+
+=head2 AllDependedOnBy
+
+Returns an array of RT::Ticket objects which (directly or indirectly)
+depends on this ticket; takes an optional 'Type' argument in the param
+hash, which will limit returned tickets to that type, as well as cause
+tickets with that type to serve as 'leaf' nodes that stops the recursive
+dependency search.
+
+=cut
+
+sub AllDependedOnBy {
+    my $self = shift;
+    my $dep = $self->DependedOnBy;
+    my %args = (
+        Type   => undef,
+	_found => {},
+	_top   => 1,
+        @_
+    );
+
+    while (my $link = $dep->Next()) {
+	next unless ($link->BaseURI->IsLocal());
+	next if $args{_found}{$link->BaseObj->Id};
+
+	if (!$args{Type}) {
+	    $args{_found}{$link->BaseObj->Id} = $link->BaseObj;
+	    $link->BaseObj->AllDependedOnBy( %args, _top => 0 );
+	}
+	elsif ($link->BaseObj->Type eq $args{Type}) {
+	    $args{_found}{$link->BaseObj->Id} = $link->BaseObj;
+	}
+	else {
+	    $link->BaseObj->AllDependedOnBy( %args, _top => 0 );
+	}
+    }
+
+    if ($args{_top}) {
+	return map { $args{_found}{$_} } sort keys %{$args{_found}};
+    }
+    else {
+	return 1;
+    }
+}
+
+# }}}
+
+# {{{ DependsOn
+
+=head2 DependsOn
+
+  This returns an RT::Links object which references all the tickets that this ticket depends on
+
+=cut
+
+sub DependsOn {
+    my $self = shift;
+    return ( $self->_Links( 'Base', 'DependsOn' ) );
+}
+
+# }}}
+
+
+
+
+# {{{ sub _Links 
+
+sub _Links {
+    my $self = shift;
+
+    #TODO: Field isn't the right thing here. but I ahave no idea what mnemonic ---
+    #tobias meant by $f
+    my $field = shift;
+    my $type  = shift || "";
+
+    unless ( $self->{"$field$type"} ) {
+        $self->{"$field$type"} = new RT::Links( $self->CurrentUser );
+            # at least to myself
+            $self->{"$field$type"}->Limit( FIELD => $field,
+                                           VALUE => $self->URI,
+                                           ENTRYAGGREGATOR => 'OR' );
+            $self->{"$field$type"}->Limit( FIELD => 'Type',
+                                           VALUE => $type )
+              if ($type);
+    }
+    return ( $self->{"$field$type"} );
+}
+
+# }}}
+
+# }}}
+
+# {{{ sub _AddLink
+
+=head2 _AddLink
+
+Takes a paramhash of Type and one of Base or Target. Adds that link to this ticket.
+
+
+=cut
+
+
+sub _AddLink {
+    my $self = shift;
+    my %args = ( Target => '',
+                 Base   => '',
+                 Type   => '',
+                 Silent => undef,
+                 @_ );
+
+
+    # Remote_link is the URI of the object that is not this ticket
+    my $remote_link;
+    my $direction;
+
+    if ( $args{'Base'} and $args{'Target'} ) {
+        $RT::Logger->debug(
+"$self tried to delete a link. both base and target were specified\n" );
+        return ( 0, $self->loc("Can't specifiy both base and target") );
+    }
+    elsif ( $args{'Base'} ) {
+        $args{'Target'} = $self->URI();
+	my $class = ref($self);
+        $remote_link    = $args{'Base'};
+        $direction      = 'Target';
+    }
+    elsif ( $args{'Target'} ) {
+        $args{'Base'} = $self->URI();
+	my $class = ref($self);
+        $remote_link  = $args{'Target'};
+        $direction    = 'Base';
+    }
+    else {
+        return ( 0, $self->loc('Either base or target must be specified') );
+    }
+
+    # {{{ Check if the link already exists - we don't want duplicates
+    use RT::Link;
+    my $old_link = RT::Link->new( $self->CurrentUser );
+    $old_link->LoadByParams( Base   => $args{'Base'},
+                             Type   => $args{'Type'},
+                             Target => $args{'Target'} );
+    if ( $old_link->Id ) {
+        $RT::Logger->debug("$self Somebody tried to duplicate a link");
+        return ( $old_link->id, $self->loc("Link already exists"), 0 );
+    }
+
+    # }}}
+
+
+    # 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} );
+
+    unless ($linkid) {
+        $RT::Logger->error("Link could not be created: ".$linkmsg);
+        return ( 0, $self->loc("Link could not be created") );
+    }
+
+    my $TransString =
+      "Record $args{'Base'} $args{Type} record $args{'Target'}.";
+
+    return ( 1, $self->loc( "Link created ([_1])", $TransString ) );
+}
+
+# }}}
+
+# {{{ sub _DeleteLink 
+
+=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
+
+=cut 
+
+sub _DeleteLink {
+    my $self = shift;
+    my %args = (
+        Base   => undef,
+        Target => undef,
+        Type   => undef,
+        @_
+    );
+
+    #we want one of base and target. we don't care which
+    #but we only want _one_
+
+    my $direction;
+    my $remote_link;
+
+    if ( $args{'Base'} and $args{'Target'} ) {
+        $RT::Logger->debug("$self ->_DeleteLink. got both Base and Target\n");
+        return ( 0, $self->loc("Can't specifiy both base and target") );
+    }
+    elsif ( $args{'Base'} ) {
+        $args{'Target'} = $self->URI();
+	$remote_link = $args{'Base'};
+    	$direction = 'Target';
+    }
+    elsif ( $args{'Target'} ) {
+        $args{'Base'} = $self->URI();
+	$remote_link = $args{'Target'};
+        $direction='Base';
+    }
+    else {
+        $RT::Logger->debug("$self: Base or Target must be specified\n");
+        return ( 0, $self->loc('Either base or target must be specified') );
+    }
+
+    my $link = new RT::Link( $self->CurrentUser );
+    $RT::Logger->debug( "Trying to load link: " . $args{'Base'} . " " . $args{'Type'} . " " . $args{'Target'} . "\n" );
+
+
+    $link->LoadByParams( Base=> $args{'Base'}, Type=> $args{'Type'}, Target=>  $args{'Target'} );
+    #it's a real link. 
+    if ( $link->id ) {
+
+        my $linkid = $link->id;
+        $link->Delete();
+
+        my $TransString = "Record $args{'Base'} no longer $args{Type} record $args{'Target'}.";
+        return ( 1, $self->loc("Link deleted ([_1])", $TransString));
+    }
+
+    #if it's not a link we can find
+    else {
+        $RT::Logger->debug("Couldn't find that link\n");
+        return ( 0, $self->loc("Link not found") );
     }
 }
 

Modified: rt/branches/rt-3.1/lib/RT/Ticket_Overlay.pm
==============================================================================
--- rt/branches/rt-3.1/lib/RT/Ticket_Overlay.pm	(original)
+++ rt/branches/rt-3.1/lib/RT/Ticket_Overlay.pm	Thu Mar 25 10:21:44 2004
@@ -185,6 +185,9 @@
 
 # }}}
 
+sub LINKTYPEMAP   { return \%LINKTYPEMAP   }
+sub LINKDIRMAP   { return \%LINKDIRMAP   }
+
 # {{{ sub Load
 
 =head2 Load
@@ -216,8 +219,8 @@
     if ( $id =~ /^\d+$/ ) {
         my $ticketid = $self->LoadById($id);
 
-        unless ($ticketid) {
-            $RT::Logger->debug("$self tried to load a bogus ticket: $id\n");
+        unless ($self->Id) {
+            $RT::Logger->crit("$self tried to load a bogus ticket: $id\n");
             return (undef);
         }
     }
@@ -2460,254 +2463,6 @@
 
 # }}}
 
-# {{{ Routines dealing with Links and Relations between tickets
-
-# {{{ Link Collections
-
-# {{{ sub Members
-
-=head2 Members
-
-  This returns an RT::Links object which references all the tickets 
-which are 'MembersOf' this ticket
-
-=cut
-
-sub Members {
-    my $self = shift;
-    return ( $self->_Links( 'Target', 'MemberOf' ) );
-}
-
-# }}}
-
-# {{{ sub MemberOf
-
-=head2 MemberOf
-
-  This returns an RT::Links object which references all the tickets that this
-ticket is a 'MemberOf'
-
-=cut
-
-sub MemberOf {
-    my $self = shift;
-    return ( $self->_Links( 'Base', 'MemberOf' ) );
-}
-
-# }}}
-
-# {{{ RefersTo
-
-=head2 RefersTo
-
-  This returns an RT::Links object which shows all references for which this ticket is a base
-
-=cut
-
-sub RefersTo {
-    my $self = shift;
-    return ( $self->_Links( 'Base', 'RefersTo' ) );
-}
-
-# }}}
-
-# {{{ ReferredToBy
-
-=head2 ReferredToBy
-
-  This returns an RT::Links object which shows all references for which this ticket is a target
-
-=cut
-
-sub ReferredToBy {
-    my $self = shift;
-    return ( $self->_Links( 'Target', 'RefersTo' ) );
-}
-
-# }}}
-
-# {{{ DependedOnBy
-
-=head2 DependedOnBy
-
-  This returns an RT::Links object which references all the tickets that depend on this one
-
-=cut
-
-sub DependedOnBy {
-    my $self = shift;
-    return ( $self->_Links( 'Target', 'DependsOn' ) );
-}
-
-# }}}
-
-
-
-=head2 HasUnresolvedDependencies
-
-  Takes a paramhash of Type (default to '__any').  Returns true if
-$self->UnresolvedDependencies returns an object with one or more members
-of that type.  Returns false otherwise
-
-
-=begin testing
-
-my $t1 = RT::Ticket->new($RT::SystemUser);
-my ($id, $trans, $msg) = $t1->Create(Subject => 'DepTest1', Queue => 'general');
-ok($id, "Created dep test 1 - $msg");
-
-my $t2 = RT::Ticket->new($RT::SystemUser);
-my ($id2, $trans, $msg2) = $t2->Create(Subject => 'DepTest2', Queue => 'general');
-ok($id2, "Created dep test 2 - $msg2");
-my $t3 = RT::Ticket->new($RT::SystemUser);
-my ($id3, $trans, $msg3) = $t3->Create(Subject => 'DepTest3', Queue => 'general', Type => 'approval');
-ok($id3, "Created dep test 3 - $msg3");
-my ($addid, $addmsg);
-ok (($addid, $addmsg) =$t1->AddLink( Type => 'DependsOn', Target => $t2->id));
-ok ($addid, $addmsg);
-ok (($addid, $addmsg) =$t1->AddLink( Type => 'DependsOn', Target => $t3->id));
-
-ok ($addid, $addmsg);
-ok ($t1->HasUnresolvedDependencies, "Ticket ".$t1->Id." has unresolved deps");
-ok (!$t1->HasUnresolvedDependencies( Type => 'blah' ), "Ticket ".$t1->Id." has no unresolved blahs");
-ok ($t1->HasUnresolvedDependencies( Type => 'approval' ), "Ticket ".$t1->Id." has unresolved approvals");
-ok (!$t2->HasUnresolvedDependencies, "Ticket ".$t2->Id." has no unresolved deps");
-;
-
-my ($rid, $rmsg)= $t1->Resolve();
-ok(!$rid, $rmsg);
-ok($t2->Resolve);
-($rid, $rmsg)= $t1->Resolve();
-ok(!$rid, $rmsg);
-ok($t3->Resolve);
-($rid, $rmsg)= $t1->Resolve();
-ok($rid, $rmsg);
-
-
-=end testing
-
-=cut
-
-sub HasUnresolvedDependencies {
-    my $self = shift;
-    my %args = (
-        Type   => undef,
-        @_
-    );
-
-    my $deps = $self->UnresolvedDependencies;
-
-    if ($args{Type}) {
-        $deps->Limit( FIELD => 'Type', 
-              OPERATOR => '=',
-              VALUE => $args{Type}); 
-    }
-    else {
-	    $deps->IgnoreType;
-    }
-
-    if ($deps->Count > 0) {
-        return 1;
-    }
-    else {
-        return (undef);
-    }
-}
-
-
-# {{{ UnresolvedDependencies 
-
-=head2 UnresolvedDependencies
-
-Returns an RT::Tickets object of tickets which this ticket depends on
-and which have a status of new, open or stalled. (That list comes from
-RT::Queue->ActiveStatusArray
-
-=cut
-
-
-sub UnresolvedDependencies {
-    my $self = shift;
-    my $deps = RT::Tickets->new($self->CurrentUser);
-
-    my @live_statuses = RT::Queue->ActiveStatusArray();
-    foreach my $status (@live_statuses) {
-        $deps->LimitStatus(VALUE => $status);
-    }
-    $deps->LimitDependedOnBy($self->Id);
-
-    return($deps);
-
-}
-
-# }}}
-
-# {{{ AllDependedOnBy
-
-=head2 AllDependedOnBy
-
-Returns an array of RT::Ticket objects which (directly or indirectly)
-depends on this ticket; takes an optional 'Type' argument in the param
-hash, which will limit returned tickets to that type, as well as cause
-tickets with that type to serve as 'leaf' nodes that stops the recursive
-dependency search.
-
-=cut
-
-sub AllDependedOnBy {
-    my $self = shift;
-    my $dep = $self->DependedOnBy;
-    my %args = (
-        Type   => undef,
-	_found => {},
-	_top   => 1,
-        @_
-    );
-
-    while (my $link = $dep->Next()) {
-	next unless ($link->BaseURI->IsLocal());
-	next if $args{_found}{$link->BaseObj->Id};
-
-	if (!$args{Type}) {
-	    $args{_found}{$link->BaseObj->Id} = $link->BaseObj;
-	    $link->BaseObj->AllDependedOnBy( %args, _top => 0 );
-	}
-	elsif ($link->BaseObj->Type eq $args{Type}) {
-	    $args{_found}{$link->BaseObj->Id} = $link->BaseObj;
-	}
-	else {
-	    $link->BaseObj->AllDependedOnBy( %args, _top => 0 );
-	}
-    }
-
-    if ($args{_top}) {
-	return map { $args{_found}{$_} } sort keys %{$args{_found}};
-    }
-    else {
-	return 1;
-    }
-}
-
-# }}}
-
-# {{{ DependsOn
-
-=head2 DependsOn
-
-  This returns an RT::Links object which references all the tickets that this ticket depends on
-
-=cut
-
-sub DependsOn {
-    my $self = shift;
-    return ( $self->_Links( 'Base', 'DependsOn' ) );
-}
-
-# }}}
-
-
-
-
 # {{{ sub _Links 
 
 sub _Links {
@@ -2744,8 +2499,6 @@
 
 # }}}
 
-# }}}
-
 # {{{ sub DeleteLink 
 
 =head2 DeleteLink
@@ -2772,43 +2525,25 @@
 
     }
 
-    #we want one of base and target. we don't care which
-    #but we only want _one_
-
-    my $direction;
-    my $remote_link;
+    my ($val, $Msg) = $self->SUPER::_DeleteLink(%args);
 
-    if ( $args{'Base'} and $args{'Target'} ) {
-        $RT::Logger->debug("$self ->_DeleteLink. got both Base and Target\n");
-        return ( 0, $self->loc("Can't specifiy both base and target") );
+    if ( !$val ) {
+        $RT::Logger->debug("Couldn't find that link\n");
+        return ( 0, $Msg );
     }
-    elsif ( $args{'Base'} ) {
-        $args{'Target'} = $self->URI();
+
+    my ($direction, $remote_link);
+
+    if ( $args{'Base'} ) {
 	$remote_link = $args{'Base'};
     	$direction = 'Target';
     }
     elsif ( $args{'Target'} ) {
-        $args{'Base'} = $self->URI();
 	$remote_link = $args{'Target'};
         $direction='Base';
     }
-    else {
-        $RT::Logger->debug("$self: Base or Target must be specified\n");
-        return ( 0, $self->loc('Either base or target must be specified') );
-    }
-
-    my $link = new RT::Link( $self->CurrentUser );
-    $RT::Logger->debug( "Trying to load link: " . $args{'Base'} . " " . $args{'Type'} . " " . $args{'Target'} . "\n" );
-
-
-    $link->LoadByParams( Base=> $args{'Base'}, Type=> $args{'Type'}, Target=>  $args{'Target'} );
-    #it's a real link. 
-    if ( $link->id ) {
 
-        my $linkid = $link->id;
-        $link->Delete();
-
-        my $TransString = "Ticket $args{'Base'} no longer $args{Type} ticket $args{'Target'}.";
+    if ( $val ) {
 	my $remote_uri = RT::URI->new( $RT::SystemUser );
     	$remote_uri->FromURI( $remote_link );
 
@@ -2819,13 +2554,7 @@
             TimeTaken => 0
         );
 
-        return ( $Trans, $self->loc("Link deleted ([_1])", $TransString));
-    }
-
-    #if it's not a link we can find
-    else {
-        $RT::Logger->debug("Couldn't find that link\n");
-        return ( 0, $self->loc("Link not found") );
+        return ( $Trans, $Msg );
     }
 }
 
@@ -2853,74 +2582,36 @@
         return ( 0, $self->loc("Permission Denied") );
     }
 
-    # Remote_link is the URI of the object that is not this ticket
-    my $remote_link;
-    my $direction;
+    my ($val, $Msg) = $self->SUPER::_AddLink(%args);
 
-    if ( $args{'Base'} and $args{'Target'} ) {
-        $RT::Logger->debug(
-"$self tried to delete a link. both base and target were specified\n" );
-        return ( 0, $self->loc("Can't specifiy both base and target") );
-    }
-    elsif ( $args{'Base'} ) {
-        $args{'Target'} = $self->URI();
-        $remote_link    = $args{'Base'};
-        $direction      = 'Target';
+    if (!$val) {
+	return ($val, $Msg);
     }
-    elsif ( $args{'Target'} ) {
-        $args{'Base'} = $self->URI();
+
+    my ($direction, $remote_link);
+    if ( $args{'Target'} ) {
         $remote_link  = $args{'Target'};
         $direction    = 'Base';
-    }
-    else {
-        return ( 0, $self->loc('Either base or target must be specified') );
-    }
-
-    # If the base isn't a URI, make it a URI. 
-    # If the target isn't a URI, make it a URI. 
-
-    # {{{ Check if the link already exists - we don't want duplicates
-    use RT::Link;
-    my $old_link = RT::Link->new( $self->CurrentUser );
-    $old_link->LoadByParams( Base   => $args{'Base'},
-                             Type   => $args{'Type'},
-                             Target => $args{'Target'} );
-    if ( $old_link->Id ) {
-        $RT::Logger->debug("$self Somebody tried to duplicate a link");
-        return ( $old_link->id, $self->loc("Link already exists"), 0 );
-    }
-
-    # }}}
-
-    # 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} );
-
-    unless ($linkid) {
-        $RT::Logger->error("Link could not be created: ".$linkmsg);
-        return ( 0, $self->loc("Link could not be created") );
+    } elsif ( $args{'Base'} ) {
+        $remote_link  = $args{'Base'};
+        $direction    = 'Target';
     }
 
-    my $TransString =
-      "Ticket $args{'Base'} $args{Type} ticket $args{'Target'}.";
-
     # Don't write the transaction if we're doing this on create
     if ( $args{'Silent'} ) {
-        return ( 1, $self->loc( "Link created ([_1])", $TransString ) );
+        return ( 1, $Msg );
     }
     else {
 	my $remote_uri = RT::URI->new( $RT::SystemUser );
     	$remote_uri->FromURI( $remote_link );
 
         #Write the transaction
-        my ( $Trans, $Msg, $TransObj ) = $self->_NewTransaction(
-                                                         Type  => 'AddLink',
-                                                         Field => $LINKDIRMAP{$args{'Type'}}->{$direction},
-							                             NewValue =>  $remote_uri->URI || $remote_link,
-                                                         TimeTaken => 0 );
-        return ( $Trans, $self->loc( "Link created ([_1])", $TransString ) );
+        my ( $Trans, $Msg, $TransObj ) = 
+	    $self->_NewTransaction(Type  => 'AddLink',
+				   Field => $LINKDIRMAP{$args{'Type'}}->{$direction},
+				   NewValue =>  $remote_uri->URI || $remote_link,
+				   TimeTaken => 0 );
+        return ( $Trans, $Msg );
     }
 
 }

Modified: rt/branches/rt-3.1/lib/RT/Tickets_Overlay.pm
==============================================================================
--- rt/branches/rt-3.1/lib/RT/Tickets_Overlay.pm	(original)
+++ rt/branches/rt-3.1/lib/RT/Tickets_Overlay.pm	Thu Mar 25 10:21:44 2004
@@ -293,12 +293,13 @@
   die "Incorrect Meta Data for $field"
     unless (defined $meta->[1] and defined $meta->[2]);
 
-  my $LinkAlias = $sb->NewAlias ('Links');
+  $sb->{_sql_linkalias} = $sb->NewAlias ('Links')
+    unless defined $sb->{_sql_linkalias};
 
   $sb->_OpenParen();
 
   $sb->_SQLLimit(
-	     ALIAS => $LinkAlias,
+	     ALIAS => $sb->{_sql_linkalias},
 	     FIELD =>   'Type',
 	     OPERATOR => '=',
 	     VALUE => $meta->[2],
@@ -309,7 +310,7 @@
     my $matchfield = ( $value  =~ /^(\d+)$/ ? "LocalTarget" : "Target" );
 
     $sb->_SQLLimit(
-	       ALIAS => $LinkAlias,
+	       ALIAS => $sb->{_sql_linkalias},
 	       ENTRYAGGREGATOR => 'AND',
 	       FIELD =>   $matchfield,
 	       OPERATOR => '=',
@@ -317,14 +318,14 @@
 	      );
 
     #If we're searching on target, join the base to ticket.id
-    $sb->Join( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'},
-	       ALIAS2 => $LinkAlias,	 FIELD2 => 'LocalBase');
+    $sb->_SQLJoin( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'},
+	       ALIAS2 => $sb->{_sql_linkalias},	 FIELD2 => 'LocalBase');
 
   } elsif ( $meta->[1] eq "From" ) {
     my $matchfield = ( $value  =~ /^(\d+)$/ ? "LocalBase" : "Base" );
 
     $sb->_SQLLimit(
-	       ALIAS => $LinkAlias,
+	       ALIAS => $sb->{_sql_linkalias},
 	       ENTRYAGGREGATOR => 'AND',
 	       FIELD =>   $matchfield,
 	       OPERATOR => '=',
@@ -332,8 +333,8 @@
 	      );
 
     #If we're searching on base, join the target to ticket.id
-    $sb->Join( ALIAS1 => 'main',     FIELD1 => $sb->{'primary_key'},
-	       ALIAS2 => $LinkAlias, FIELD2 => 'LocalTarget');
+    $sb->_SQLJoin( ALIAS1 => 'main',     FIELD1 => $sb->{'primary_key'},
+	       ALIAS2 => $sb->{_sql_linkalias}, FIELD2 => 'LocalTarget');
 
   } else {
     die "Invalid link direction '$meta->[1]' for $field\n";
@@ -462,11 +463,11 @@
   $sb->_OpenParen;
 
   # Join Transactions To Attachments
-  $sb->Join( ALIAS1 => $sb->{_sql_trattachalias}, FIELD1 => 'TransactionId',
+  $sb->_SQLJoin( ALIAS1 => $sb->{_sql_trattachalias}, FIELD1 => 'TransactionId',
 	     ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'id');
 
   # Join Transactions to Tickets
-  $sb->Join( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'}, # UGH!
+  $sb->_SQLJoin( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'}, # UGH!
 	     ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'Ticket');
 
   my $d = new RT::Date( $sb->CurrentUser );
@@ -537,11 +538,11 @@
   $sb->_OpenParen;
 
   # Join Transactions To Attachments
-  $sb->Join( ALIAS1 => $sb->{_sql_trattachalias}, FIELD1 => 'TransactionId',
+  $sb->_SQLJoin( ALIAS1 => $sb->{_sql_trattachalias}, FIELD1 => 'TransactionId',
 	     ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'id');
 
   # Join Transactions to Tickets
-  $sb->Join( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'}, # UGH!
+  $sb->_SQLJoin( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'}, # UGH!
 	     ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'Ticket');
 
   #Search for the right field
@@ -615,7 +616,7 @@
 		   VALUE => 'RT::Ticket-Role',
 		   ENTRYAGGREGATOR => 'AND');
 
-  $self->Join(ALIAS1 => $groups, FIELD1 => 'Instance',
+  $self->_SQLJoin(ALIAS1 => $groups, FIELD1 => 'Instance',
 	      ALIAS2 => 'main',   FIELD2 => 'id');
   # }}}
 
@@ -630,10 +631,10 @@
 		     ENTRYAGGREGATOR => 'AND');
   }
 
-  $self->Join (ALIAS1 => $groups,  FIELD1 => 'id',
+  $self->_SQLJoin (ALIAS1 => $groups,  FIELD1 => 'id',
 	       ALIAS2 => $groupmembers, FIELD2 => 'GroupId');
 
-  $self->Join( ALIAS1 => $groupmembers, FIELD1 => 'MemberId',
+  $self->_SQLJoin( ALIAS1 => $groupmembers, FIELD1 => 'MemberId',
 	       ALIAS2 => $users, FIELD2 => 'id');
 
  $self->_CloseParen;
@@ -670,7 +671,7 @@
 			OPERATOR => '=',
 			VALUE =>    $restriction->{'TARGET'} );
     #If we're searching on target, join the base to ticket.id
-    $self->Join( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
+    $self->_SQLJoin( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
 		 ALIAS2 => $LinkAlias,
 		 FIELD2 => 'LocalBase');
   }
@@ -691,7 +692,7 @@
 			OPERATOR => '=',
 			VALUE =>    $restriction->{'BASE'} );
     #If we're searching on base, join the target to ticket.id
-    $self->Join( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
+    $self->_SQLJoin( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'},
 		 ALIAS2 => $LinkAlias,
 		 FIELD2 => 'LocalTarget')
   }
@@ -759,7 +760,7 @@
     $TicketCFs = $self->{_sql_keywordalias}{$cfid};
   } else {
     $TicketCFs = $self->{_sql_keywordalias}{$cfid} =
-      $self->Join( TYPE   => 'left',
+      $self->_SQLJoin( TYPE   => 'left',
 		   ALIAS1 => 'main',
 		   FIELD1 => 'id',
 		   TABLE2 => 'TicketCustomFieldValues',

Modified: rt/branches/rt-3.1/lib/RT/Tickets_Overlay_SQL.pm
==============================================================================
--- rt/branches/rt-3.1/lib/RT/Tickets_Overlay_SQL.pm	(original)
+++ rt/branches/rt-3.1/lib/RT/Tickets_Overlay_SQL.pm	Thu Mar 25 10:21:44 2004
@@ -48,6 +48,7 @@
   $self->{'_sql_subclause'}     = "a";
   $self->{'_sql_first'}         = 0;
   $self->{'_sql_opstack'}       = [''];
+  $self->{'_sql_linkalias'}    = undef;
   $self->{'_sql_transalias'}    = undef;
   $self->{'_sql_trattachalias'} = undef;
   $self->{'_sql_keywordalias'}  = undef;
@@ -63,8 +64,18 @@
   # All SQL stuff goes into one SB subclause so we can deal with all
   # the aggregation
   my $this = shift;
+
   $this->SUPER::Limit(@_,
                       SUBCLAUSE => 'ticketsql');
+}
+
+sub _SQLJoin {
+  # All SQL stuff goes into one SB subclause so we can deal with all
+  # the aggregation
+  my $this = shift;
+
+  $this->SUPER::Join(@_,
+		     SUBCLAUSE => 'ticketsql');
 }
 
 # Helpers

Modified: rt/branches/rt-3.1/lib/RT/Transactions_Overlay.pm
==============================================================================
--- rt/branches/rt-3.1/lib/RT/Transactions_Overlay.pm	(original)
+++ rt/branches/rt-3.1/lib/RT/Transactions_Overlay.pm	Thu Mar 25 10:21:44 2004
@@ -69,12 +69,10 @@
     my $Transaction = $self->SUPER::Next();
     if ((defined($Transaction)) and (ref($Transaction))) {
 	if ($Transaction->__Value('Type') =~ /^Comment/ && 
-	    ($Transaction->TicketObj->QueueObj->CurrentUserHasRight('ShowTicketComments') ||
-	     $Transaction->TicketObj->CurrentUserHasRight('ShowTicketComments'))) {
+	    $Transaction->TicketObj->CurrentUserHasRight('ShowTicketComments')) {
 	    return($Transaction);
 	} elsif ($Transaction->__Value('Type') !~ /^Comment/ && 
-		 ($Transaction->TicketObj->QueueObj->CurrentUserHasRight('ShowTicketComments') ||
-		  $Transaction->TicketObj->CurrentUserHasRight('ShowTicket'))) {
+		 $Transaction->TicketObj->CurrentUserHasRight('ShowTicket')) {
 	    return($Transaction);
 	}
 

Modified: rt/branches/rt-3.1/lib/RT/URI.pm
==============================================================================
--- rt/branches/rt-3.1/lib/RT/URI.pm	(original)
+++ rt/branches/rt-3.1/lib/RT/URI.pm	Thu Mar 25 10:21:44 2004
@@ -104,12 +104,12 @@
 
     return undef unless ($uri);
 
-	my $scheme;
-	# Special case: integers passed in as URIs must be ticket ids
-	if ($uri =~ /^(\d+)$/) {
-		$scheme = "fsck.com-rt";
-	} elsif ($uri =~ /^((?:\w|\.|-)+?):/) {
-         $scheme = $1;
+    my $scheme;
+    # Special case: integers passed in as URIs must be ticket ids
+    if ($uri =~ /^(\d+)$/) {
+	$scheme = "fsck.com-rt";
+    } elsif ($uri =~ /^((?:\w|\.|-)+?):/) {
+	$scheme = $1;
     }
     else {
         $RT::Logger->warning("$self Could not determine a URI scheme for $uri");



More information about the Rt-commit mailing list