[Rt-commit] rt branch, master, updated. rt-4.0.8-567-g4168ccd

Alex Vandiver alexmv at bestpractical.com
Tue Nov 20 18:02:26 EST 2012


The branch, master has been updated
       via  4168ccd38af955880ac418a2cada9a348d447216 (commit)
       via  8fce29da0d28ed9ccbfff21f5b94b5c61e980364 (commit)
       via  8430d89d0fb907ff587322da7f0a1682f7da306b (commit)
       via  0538e83f2156db7bd774505ea5c1bcbe6e55b2f3 (commit)
       via  bbe7b408d18bc2ebcf13fb9bbcbd42b4714aea10 (commit)
       via  e4edcd64fc2a32e8142520f220b33dcb34071f85 (commit)
       via  bb03d9260c13efc829def6a8133c0dcb69d05d7e (commit)
       via  cc946a9f16d120c371714b31947384620a156d02 (commit)
       via  6dc58c73b6c55f1232436874b55ec38bfe90689a (commit)
       via  1e54ce8b095d6d71ff6e5ad6500a9aef7beaeb05 (commit)
       via  76a9d8dc934c014c86279b1c3b716a9b40609df7 (commit)
       via  eae7599d2282029137e62099b9e9c453ff715274 (commit)
       via  417945f7429832f4543cc0a3df9bb5721ffccf8d (commit)
       via  5b833f649cd754e27bba672891d4ee2635e5d7ed (commit)
       via  4effe0cca3dc163e2d4444432245c48db6354f10 (commit)
       via  7821ff1e221032408f6bad2386618ce96df5519f (commit)
       via  92d78a8606c28c265f5398541864db66e53c95d4 (commit)
      from  234384add4264afccf0d387641eade924ec21626 (commit)

Summary of changes:
 docs/UPGRADING-4.2                                 |   6 +
 lib/RT/Action/CreateTickets.pm                     |  74 +-------
 lib/RT/Interface/Web.pm                            |  52 ++++--
 lib/RT/Link.pm                                     |  64 ++++++-
 lib/RT/Record.pm                                   | 197 +++++++++++++--------
 lib/RT/Shredder/Link.pm                            |   2 +-
 lib/RT/Test.pm                                     |   2 +-
 lib/RT/Ticket.pm                                   | 184 ++-----------------
 share/html/Elements/EditLinks                      |  24 +--
 share/html/Elements/RT__Ticket/ColumnMap           |   6 +-
 share/html/Elements/ShowLinks                      | 155 +++++-----------
 .../ShowAttachments => Elements/ShowLinksOfType}   | 117 ++++++------
 share/html/Elements/ShowRelationLabel              |  30 +++-
 share/html/Ticket/Elements/ShowMembers             |  74 --------
 share/html/Ticket/Elements/ShowParents             |  63 -------
 share/html/Ticket/Elements/ShowSummary             |   2 +-
 share/html/m/ticket/show                           |   4 +-
 17 files changed, 398 insertions(+), 658 deletions(-)
 copy share/html/{Ticket/Elements/ShowAttachments => Elements/ShowLinksOfType} (56%)
 delete mode 100644 share/html/Ticket/Elements/ShowMembers
 delete mode 100644 share/html/Ticket/Elements/ShowParents

- Log -----------------------------------------------------------------
commit 4168ccd38af955880ac418a2cada9a348d447216
Merge: 234384a 8fce29d
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Tue Nov 20 17:48:08 2012 -0500

    Merge branch '4.2/link-api-refactoring'
    
    Conflicts:
    	lib/RT/Interface/Web.pm
    	lib/RT/Record.pm
    	share/html/Elements/ShowLinks

diff --cc lib/RT/Interface/Web.pm
index 5a7f230,673ce42..c9928c6
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@@ -1780,27 -1639,56 +1780,14 @@@ sub CreateTicket 
              : ( $ARGS{'AttachTickets'} ) );
      }
  
 -    foreach my $arg ( keys %ARGS ) {
 -        next if $arg =~ /-(?:Magic|Category)$/;
 -
 -        if ( $arg =~ /^Object-RT::Transaction--CustomField-/ ) {
 -            $create_args{$arg} = $ARGS{$arg};
 -        }
 -
 -        # Object-RT::Ticket--CustomField-3-Values
 -        elsif ( $arg =~ /^Object-RT::Ticket--CustomField-(\d+)/ ) {
 -            my $cfid = $1;
 -
 -            my $cf = RT::CustomField->new( $session{'CurrentUser'} );
 -            $cf->SetContextObject( $Queue );
 -            $cf->Load($cfid);
 -            unless ( $cf->id ) {
 -                $RT::Logger->error( "Couldn't load custom field #" . $cfid );
 -                next;
 -            }
 -
 -            if ( $arg =~ /-Upload$/ ) {
 -                $create_args{"CustomField-$cfid"} = _UploadedFile($arg);
 -                next;
 -            }
 -
 -            my $type = $cf->Type;
 -
 -            my @values = ();
 -            if ( ref $ARGS{$arg} eq 'ARRAY' ) {
 -                @values = @{ $ARGS{$arg} };
 -            } elsif ( $type =~ /text/i ) {
 -                @values = ( $ARGS{$arg} );
 -            } else {
 -                no warnings 'uninitialized';
 -                @values = split /\r*\n/, $ARGS{$arg};
 -            }
 -            @values = grep length, map {
 -                s/\r+\n/\n/g;
 -                s/^\s+//;
 -                s/\s+$//;
 -                $_;
 -                }
 -                grep defined, @values;
 -
 -            $create_args{"CustomField-$cfid"} = \@values;
 -        }
 -    }
 +    my %cfs = ProcessObjectCustomFieldUpdatesForCreate(
 +        ARGSRef         => \%ARGS,
 +        ContextObject   => $Queue,
 +    );
  
-     # 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} ];
- 
-     }
+     my %links = ProcessLinksForCreate( ARGSRef => \%ARGS );
  
-     my ( $id, $Trans, $ErrMsg ) = $Ticket->Create(%create_args, %cfs);
 -    my ( $id, $Trans, $ErrMsg ) = $Ticket->Create(%create_args, %links);
++    my ( $id, $Trans, $ErrMsg ) = $Ticket->Create(%create_args, %links, %cfs);
      unless ($id) {
          Abort($ErrMsg);
      }
diff --cc lib/RT/Record.pm
index 2c021ec,3b524f8..21905a3
--- a/lib/RT/Record.pm
+++ b/lib/RT/Record.pm
@@@ -1386,62 -1406,69 +1406,99 @@@ sub _DeleteLink 
      }
  
      my $link = RT::Link->new( $self->CurrentUser );
-     $RT::Logger->debug( "Trying to load link: " . $args{'Base'} . " " . $args{'Type'} . " " . $args{'Target'} );
- 
+     $RT::Logger->debug( "Trying to load link: "
+             . $args{'Base'} . " "
+             . $args{'Type'} . " "
+             . $args{'Target'} );
+ 
+     $link->LoadByParams(
+         Base   => $args{'Base'},
+         Type   => $args{'Type'},
+         Target => $args{'Target'}
+     );
  
-     $link->LoadByParams( Base=> $args{'Base'}, Type=> $args{'Type'}, Target=>  $args{'Target'} );
-     #it's a real link. 
+     unless ($link->id) {
+         $RT::Logger->debug("Couldn't find that link");
+         return ( 0, $self->loc("Link not found") );
+     }
  
-     if ( $link->id ) {
-         my $basetext = $self->FormatLink(Object => $link->BaseObj,
+     my $basetext = $self->FormatLink(Object   => $link->BaseObj,
                                       FallBack => $args{Base});
-         my $targettext = $self->FormatLink(Object => $link->TargetObj,
+     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);
+     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) );
      }
  
-     #if it's not a link we can find
-     else {
-         $RT::Logger->debug("Couldn't find that link");
-         return ( 0, $self->loc("Link not found") );
+     # 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     => $RT::Link::DIRMAP{$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          => $RT::Link::DIRMAP{$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);
+ }
  
 +=head1 LockForUpdate
 +
 +In a database transaction, gains an exclusive lock on the row, to
 +prevent race conditions.  On SQLite, this is a "RESERVED" lock on the
 +entire database.
 +
 +=cut
 +
 +sub LockForUpdate {
 +    my $self = shift;
 +
 +    my $pk = $self->_PrimaryKey;
 +    my $id = @_ ? $_[0] : $self->$pk;
 +    $self->_expire if $self->isa("DBIx::SearchBuilder::Record::Cachable");
 +    if (RT->Config->Get('DatabaseType') eq "SQLite") {
 +        # SQLite does DB-level locking, upgrading the transaction to
 +        # "RESERVED" on the first UPDATE/INSERT/DELETE.  Do a no-op
 +        # UPDATE to force the upgade.
 +        return RT->DatabaseHandle->dbh->do(
 +            "UPDATE " .$self->Table.
 +                " SET $pk = $pk WHERE 1 = 0");
 +    } else {
 +        return $self->_LoadFromSQL(
 +            "SELECT * FROM ".$self->Table
 +                ." WHERE $pk = ? FOR UPDATE",
 +            $id,
 +        );
 +    }
 +}
 +
  =head2 _NewTransaction  PARAMHASH
  
  Private function to create a new RT::Transaction object for this ticket update
diff --cc share/html/Elements/EditLinks
index e293d56,f3af89f..573797b
mode 100644,100755..100644
--- a/share/html/Elements/EditLinks
+++ b/share/html/Elements/EditLinks
@@@ -155,10 -155,9 +155,10 @@@
      <td class="entry"><input name="<%$id%>-RefersTo" /></td>
    </tr>
    <tr>
-     <td class="label"><& ShowRelationLabel, id => $id, Label => loc('Referred to by'), Relation => 'ReferredToBy' &>:</td>
+     <td class="label"><& ShowRelationLabel, Object => $Object, Label => loc('Referred to by'), Relation => 'ReferredToBy' &>:</td>
      <td class="entry"> <input name="RefersTo-<%$id%>" /></td>
    </tr>
 +  <& /Elements/EditCustomFields, Object => $Object, Grouping => 'Links', InTable => 1 &>
  % $m->callback( CallbackName => 'NewLink' );
  </table>
  </td>
diff --cc share/html/Elements/ShowLinks
index b6a5cc7,1f3501a..40356fe
mode 100644,100755..100644
--- a/share/html/Elements/ShowLinks
+++ b/share/html/Elements/ShowLinks
@@@ -46,135 -46,62 +46,62 @@@
  %#
  %# END BPS TAGGED BLOCK }}}
  <table>
+ % for my $type (@display) {
    <tr>
-     <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Depends on'), Relation => 'DependsOn' &>:\
- % if ($can_create) {
-         <span class="create">(<a href="<%$clone->{'DependsOn-new'}%>"><% loc('Create') %></a>)</span>
- % }
-     </td>
-     <td class="value">
- <%PERL>
- my ( $depends_on, @active, @inactive, @not_tickets );
- $depends_on = $Ticket->DependsOn;
- 
- while ( my $link = $depends_on->Next ) {
-     my $target = $link->TargetObj;
-     if ( $target && $target->isa('RT::Ticket') ) {
-         if ( $target->QueueObj->IsInactiveStatus( $target->Status ) ) {
-             push( @inactive, $link->TargetURI );
-         }
-         else {
-             push( @active, $link->TargetURI );
-         }
-     }
-     else {
-         push( @not_tickets, $link->TargetURI );
-     }
- }
- </%PERL>
- <ul>
- % for my $Link (@not_tickets, @active, @inactive) {
- <li><& ShowLink, URI => $Link &></li>
- % }
- </ul>
-     </td>
-   </tr>
-   <tr>
-     <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Depended on by'), Relation => 'DependedOnBy' &>:\
- % if ($can_create) {
-         <span class="create">(<a href="<%$clone->{'new-DependsOn'}%>"><% loc('Create') %></a>)</span>
- % }
-     </td>
-     <td class="value">
- <ul>
- % while (my $Link = $Ticket->DependedOnBy->Next) {
- <li><& ShowLink, URI => $Link->BaseURI &></li>
- % }
- </ul>
-     </td>
-   </tr>
-   <tr>
-     <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Parents'), Relation => 'Parents' &>:\
- % if ($can_create) {
-         <span class="create">(<a href="<%$clone->{'MemberOf-new'}%>"><% loc('Create') %></a>)</span>
- % }
-     </td>
-     <td class="value"><& /Ticket/Elements/ShowParents, Ticket => $Ticket &></td>
-   </tr>
-   <tr>
-     <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Children'), Relation => 'Children' &>:\
- % if ($can_create) {
-         <span class="create">(<a href="<%$clone->{'new-MemberOf'}%>"><% loc('Create') %></a>)</span>
- % }
-     </td>
-     <td class="value"><& /Ticket/Elements/ShowMembers, Ticket => $Ticket &></td>
-   </tr>
-   <tr>
-     <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Refers to'), Relation => 'RefersTo' &>:\
- % if ($can_create) {
-         <span class="create">(<a href="<%$clone->{'RefersTo-new'}%>"><% loc('Create') %></a>)</span>
- % }
+     <td class="labeltop">
+       <& ShowRelationLabel, Object => $Object, Label => $labels{$type}, Relation => $type &>:\
+ %     if ($clone{$type}) {
+         <span class="create">(<a href="<% $clone{$type} %>"><% loc('Create') %></a>)</span>
+ %     }
      </td>
      <td class="value">
- <ul>
- % while (my $Link = $Ticket->RefersTo->Next) {
- <li><& ShowLink, URI => $Link->TargetURI &></li>
- % }
- </ul>
+       <& ShowLinksOfType, Object => $Object, Type => $type, Recurse => ($type eq 'Members') &>
      </td>
    </tr>
-   <tr>
-     <td class="labeltop"><& ShowRelationLabel, id => $id, Label => loc('Referred to by'), Relation => 'ReferredToBy' &>:\
- % if ($can_create) {
-         <span class="create">(<a href="<%$clone->{'new-RefersTo'}%>"><% loc('Create') %></a>)</span>
  % }
-     </td>
-     <td class="value">
-     <ul>
- % while (my $Link = $Ticket->ReferredToBy->Next) {
- % next if (UNIVERSAL::isa($Link->BaseObj, 'RT::Ticket')  && $Link->BaseObj->Type eq 'reminder');
- <li><& ShowLink, URI => $Link->BaseURI &></li>
- % }
- </ul>
-     </td>
-   </tr>
-   <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket, Grouping => 'Links', Table => 0 &>
 -
  % # Allow people to add more rows to the table
  % $m->callback( %ARGS );
++  <& /Elements/ShowCustomFields, Object => $Object, Grouping => 'Links', Table => 0 &>
  </table>
  <%INIT>
+ my @display = qw(DependsOn DependedOnBy MemberOf Members RefersTo ReferredToBy);
+ my %labels  = (
+     DependsOn       => loc('Depends on'),
+     DependedOnBy    => loc('Depended on by'),
+     MemberOf        => loc('Parents'),
+     Members         => loc('Children'),
+     RefersTo        => loc('Refers to'),
+     ReferredToBy    => loc('Referred to by'),
+ );
+ my %clone;
  
- my $id = $Ticket->id;
+ if (    $Object->isa("RT::Ticket")
+     and $Object->QueueObj->CurrentUserHasRight('CreateTicket'))
+ {
+     my $id = $Object->id;
+     my $path
+         = RT->Config->Get('WebPath')
+         . '/Ticket/Create.html?Queue='
+         . $Object->Queue
+         . '&CloneTicket='
+         . $id;
  
- my $clone = {};
- my $path
-     = RT->Config->Get('WebPath')
-     . '/Ticket/Create.html?Queue='
-     . $Ticket->Queue
-     . '&CloneTicket='
-     . $id;
- my $can_create = $Ticket->QueueObj->CurrentUserHasRight('CreateTicket');
+     for my $relation (@display) {
+         my $mode  = $RT::Link::TYPEMAP{$relation}->{Mode};
+         my $type  = $RT::Link::TYPEMAP{$relation}->{Type};
+         my $field = $mode eq 'Base' ? 'new-' . $type : $type . '-new';
+         my @copy  = ($id);
  
- for my $relation (
-     qw(RefersTo ReferredToBy)) {
-     my $mode  = $RT::Ticket::LINKTYPEMAP{$relation}->{Mode};
-     my $type  = $RT::Ticket::LINKTYPEMAP{$relation}->{Type};
-     my $other = "Local" . $mode;
-     my $field = $mode eq 'Base' ? 'new-' . $type : $type . '-new';
-     $clone->{$field} 
-         = $path . "&$field="
-         . join( '%20',
-         ( map { $_->$other() } @{ $Ticket->$relation->ItemsArrayRef } ), $id );
- }
+         # Canonicalized type captures both directions
+         if ($type eq "RefersTo") {
+             my $other = "Local" . $mode;
+             push @copy, map { $_->$other() } @{ $Object->$relation->ItemsArrayRef };
+         }
  
- for my $relation ( qw(MemberOf Members DependsOn DependedOnBy)) {
-     my $mode  = $RT::Ticket::LINKTYPEMAP{$relation}->{Mode};
-     my $type  = $RT::Ticket::LINKTYPEMAP{$relation}->{Type};
-     my $field = $mode eq 'Base' ? 'new-' . $type : $type . '-new';
-     $clone->{$field} = $path . "&$field=$id";
+         $clone{$relation} = "$path&$field=" . join('%20', grep { $_ } @copy);
+     }
  }
- 
  </%INIT>
  <%ARGS>
- $Ticket => undef
+ $Object
  </%ARGS>
diff --cc share/html/Ticket/Elements/ShowSummary
index 2fbc46c,0f0a0a6..618e23c
mode 100644,100755..100644
--- a/share/html/Ticket/Elements/ShowSummary
+++ b/share/html/Ticket/Elements/ShowSummary

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


More information about the Rt-commit mailing list