[Bps-public-commit] rt-extension-cloneticket-withdata branch, master, updated. 892fcbe129336bee4e96340075920f4b87fdf19d

Alex M Vandiver alexmv at bestpractical.com
Tue Dec 1 15:18:39 EST 2009


The branch, master has been updated
       via  892fcbe129336bee4e96340075920f4b87fdf19d (commit)
      from  b06df32628de2c557775ed79803a5d346fb0f3b9 (commit)

Summary of changes:
 Changes                                            |   19 ++
 MANIFEST                                           |   23 ++
 Makefile.PL                                        |    6 +
 README                                             |   24 +++
 .../CloneTicket/Elements/MessageBox/AfterTextArea  |   52 +++++
 html/Callbacks/CloneTicket/Ticket/Create.html/Init |   43 ++++
 .../CloneTicket/Ticket/Display.html/BeforeDisplay  |   48 +++++
 .../Ticket/Elements/ShowTransaction/ModifyDisplay  |   37 ++++
 .../CloneTicket/Ticket/Elements/Tabs/Default       |   42 ++++
 html/Ticket/Clone/index.html                       |  216 ++++++++++++++++++++
 lib/RT/Extension/CloneTicket/WithData.pm           |    9 +
 patch_on_3.6.5                                     |  213 +++++++++++++++++++
 patch_on_3.8                                       |  155 ++++++++++++++
 13 files changed, 887 insertions(+), 0 deletions(-)
 create mode 100644 Changes
 create mode 100644 MANIFEST
 create mode 100644 Makefile.PL
 create mode 100644 README
 create mode 100644 html/Callbacks/CloneTicket/Elements/MessageBox/AfterTextArea
 create mode 100644 html/Callbacks/CloneTicket/Ticket/Create.html/Init
 create mode 100644 html/Callbacks/CloneTicket/Ticket/Display.html/BeforeDisplay
 create mode 100644 html/Callbacks/CloneTicket/Ticket/Elements/ShowTransaction/ModifyDisplay
 create mode 100644 html/Callbacks/CloneTicket/Ticket/Elements/Tabs/Default
 create mode 100644 html/Ticket/Clone/index.html
 create mode 100644 lib/RT/Extension/CloneTicket/WithData.pm
 create mode 100644 patch_on_3.6.5
 create mode 100644 patch_on_3.8

- Log -----------------------------------------------------------------
commit 892fcbe129336bee4e96340075920f4b87fdf19d
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Tue Dec 1 15:17:50 2009 -0500

    Stripped customer-specific information and renamed

diff --git a/Changes b/Changes
new file mode 100644
index 0000000..614c8f7
--- /dev/null
+++ b/Changes
@@ -0,0 +1,19 @@
+Revision history for RT-Extension-CloneTicket-WithData
+
+0.07 Tue Dec  1 15:16:17 EST 2009
+    * Stripped customer-specific information and renamed; first public
+      release
+0.06 Tue Aug 25 11:13:59 CST 2009
+    * redirect to create page if the Queue parameter exists
+0.05 Wed Aug 19 17:05:17 EST 2009
+    * Invert the sense of the transaction checkboxes
+0.04 Fri Jul 31 20:09:01 CST 2009
+    * show the transations part more clearly
+0.03 Wed Jul 29 20:18:42 CST 2009
+    * Clone action add RefersTo-new link
+    * show Create trans too, and let it act as Reply if it's selected.
+0.02 Tue Jul 28 18:51:35 CST 2009
+    Clone binary CFs too
+0.01 Tue Jun 30 20:13:06 CST 2009
+       Initial release.
+
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..50fd2a2
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,23 @@
+Changes
+html/Callbacks/CloneTicket/Elements/MessageBox/AfterTextArea
+html/Callbacks/CloneTicket/Ticket/Create.html/Init
+html/Callbacks/CloneTicket/Ticket/Display.html/BeforeDisplay
+html/Callbacks/CloneTicket/Ticket/Elements/ShowTransaction/ModifyDisplay
+html/Callbacks/CloneTicket/Ticket/Elements/Tabs/Default
+html/Ticket/Clone/index.html
+inc/Module/Install.pm
+inc/Module/Install/Base.pm
+inc/Module/Install/Can.pm
+inc/Module/Install/Fetch.pm
+inc/Module/Install/Makefile.pm
+inc/Module/Install/Metadata.pm
+inc/Module/Install/RTx.pm
+inc/Module/Install/Win32.pm
+inc/Module/Install/WriteAll.pm
+lib/RT/Extension/CloneTicket/WithData.pm
+Makefile.PL
+MANIFEST			This list of files
+META.yml
+patch_on_3.6.5
+patch_on_3.8
+README
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644
index 0000000..347d2dd
--- /dev/null
+++ b/Makefile.PL
@@ -0,0 +1,6 @@
+use inc::Module::Install;
+RTx('RT-Extension-CloneTicket-WithData');
+author('sunnavy <sunnavy at bestpractical.com>');
+license('perl');
+
+&WriteAll;
diff --git a/README b/README
new file mode 100644
index 0000000..64e3278
--- /dev/null
+++ b/README
@@ -0,0 +1,24 @@
+RT-Extension-CloneTicket-WithData version 0.04
+
+How to install:
+
+1. Run "perl Makefile.PL"
+
+2. Run "make"
+
+3. Run "make install" (you may need root permissions)
+
+4. patch RT
+   If you're running 3.6.5:
+    $ patch -p0 -d /opt/rt3 < patch_on_3.6.5
+
+   If you're running 3.8:
+    $ patch -p0 -d /opt/rt3 < patch_on_3.8
+ 
+5. Additionally, if you're running 3.8, you'll need to add
+   "RT::Extension::CloneTicket::WithData" to @Plugins in
+   etc/RT_SiteConfig.pm.  For example:
+    Set(@Plugins, qw(RT::Extension::CloneTicket::WithData));
+
+6. Clear RT's mason cache and restart the web server to make sure the
+   extension is incorporated.
diff --git a/html/Callbacks/CloneTicket/Elements/MessageBox/AfterTextArea b/html/Callbacks/CloneTicket/Elements/MessageBox/AfterTextArea
new file mode 100644
index 0000000..2b300d8
--- /dev/null
+++ b/html/Callbacks/CloneTicket/Elements/MessageBox/AfterTextArea
@@ -0,0 +1,52 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%#  Copyright (c) 2002-2003 Jesse Vincent <jesse at bestpractical.com>
+%#  
+%#  This program is free software; you can redistribute it and/or modify
+%#  it under the terms of version 2 of the GNU General Public License 
+%#  as published by the Free Software Foundation.
+%# 
+%#  A copy of that license should have arrived with this
+%#  software, but in any event can be snarfed from www.gnu.org.
+%# 
+%#  This program is distributed in the hope that it will be useful,
+%#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+%#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%#  GNU General Public License for more details.
+%# 
+%# END LICENSE BLOCK
+<div id="ticket-history">
+<input type="hidden" name="Transactions" value="<% join ',', @ids %>" /></td>
+<table>
+% for my $id ( sort keys %Content ) {
+<tr>
+<td><input type="checkbox" name="DeleteTransactions" value="<%$id%>" checked="checked"/></td>
+<td><% $Content{$id} |n%></td>
+</tr>
+% }
+</table>
+</div>
+<%init>
+my @Transactions;
+my %Content;
+my @ids;
+if ( $m->callers(-2) && $m->callers(-2)->path eq '/Ticket/Create.html' ) {
+    my %args = $m->request_args;
+    if ( $args{Transactions} ) {
+        @ids = split /,/, $args{Transactions};
+        my $number = 1;
+        for my $id ( @ids ) {
+            my $txn = RT::Transaction->new( $session{CurrentUser});
+            my ( $ret, $msg ) = $txn->Load( $id );
+            if ( $ret ) {
+                $Content{$id} = $m->scomp( '/Ticket/Elements/ShowTransaction',
+                        Transaction => $txn, ShowTitleBarCommands => 0, Ticket
+                        => $txn->TicketObj, RowNum => $number++ );
+            }
+            else {
+                $RT::Logger->error( "failed to load transcaction $id: $msg" );
+            }
+        } 
+    }
+}
+</%init>
diff --git a/html/Callbacks/CloneTicket/Ticket/Create.html/Init b/html/Callbacks/CloneTicket/Ticket/Create.html/Init
new file mode 100644
index 0000000..43c03eb
--- /dev/null
+++ b/html/Callbacks/CloneTicket/Ticket/Create.html/Init
@@ -0,0 +1,43 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%#  Copyright (c) 2002-2003 Jesse Vincent <jesse at bestpractical.com>
+%#  
+%#  This program is free software; you can redistribute it and/or modify
+%#  it under the terms of version 2 of the GNU General Public License 
+%#  as published by the Free Software Foundation.
+%# 
+%#  A copy of that license should have arrived with this
+%#  software, but in any event can be snarfed from www.gnu.org.
+%# 
+%#  This program is distributed in the hope that it will be useful,
+%#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+%#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%#  GNU General Public License for more details.
+%# 
+%# END LICENSE BLOCK
+<%INIT>
+my $CloneTicket = $ARGS{ARGSRef}->{CloneTicket};
+if ( $CloneTicket ) {
+    my $CloneTicketObj;
+    $CloneTicketObj = RT::Ticket->new( $session{CurrentUser} );
+    $CloneTicketObj->Load($CloneTicket) or Abort(loc("Ticket could not be loaded"));
+    my $cfs = $CloneTicketObj->QueueObj->TicketCustomFields();
+    $session{CloneCustomField} = {};
+    while ( my $cf = $cfs->Next ) {
+        if ( $cf->Type =~ /Image|Binary/i ) {
+            my $cf_id = $cf->id;
+            my $cf_values = $CloneTicketObj->CustomFieldValues( $cf_id );
+            next unless $cf_values->Count > 0;
+            $session{CloneCustomField}{$cf_id} = [];
+            while ( my $value = $cf_values->Next ) {
+                next unless $value->id;
+                push @{$session{CloneCustomField}{$cf->id}}, {
+                    Id => $value->Id,
+                    Value => $value->Content,
+                    LargeContent => $value->LargeContent,
+               };
+            }
+        }
+    }
+}
+</%INIT>
diff --git a/html/Callbacks/CloneTicket/Ticket/Display.html/BeforeDisplay b/html/Callbacks/CloneTicket/Ticket/Display.html/BeforeDisplay
new file mode 100644
index 0000000..5b63bd4
--- /dev/null
+++ b/html/Callbacks/CloneTicket/Ticket/Display.html/BeforeDisplay
@@ -0,0 +1,48 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%#  Copyright (c) 2002-2003 Jesse Vincent <jesse at bestpractical.com>
+%#  
+%#  This program is free software; you can redistribute it and/or modify
+%#  it under the terms of version 2 of the GNU General Public License 
+%#  as published by the Free Software Foundation.
+%# 
+%#  A copy of that license should have arrived with this
+%#  software, but in any event can be snarfed from www.gnu.org.
+%# 
+%#  This program is distributed in the hope that it will be useful,
+%#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+%#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%#  GNU General Public License for more details.
+%# 
+%# END LICENSE BLOCK
+<%INIT>
+my $Ticket = $ARGS{TicketObj};
+return unless $Ticket;
+# yeah, the TicketObj arg is a ref to RT::Ticket object, I don't know why
+$Ticket = $$Ticket;
+my %args = $m->request_args;
+if ( $args{Transactions} ) {
+    my @Transactions = split /,/, $args{Transactions};
+    my @DeleteTransactions = ref $args{DeleteTransactions} ? 
+        @{$args{DeleteTransactions}} : $args{DeleteTransactions};
+    my %delete_hash = map { $_ => 1 } @DeleteTransactions;
+
+for my $id ( @Transactions ) {
+    next if $delete_hash{$id};
+    my $txn = RT::Transaction->new( $session{CurrentUser} );
+    my ( $ret, $msg ) = $txn->Load( $id );
+    if ( $ret ) {
+        if ( $txn->Type eq 'Create' || $txn->Type eq 'Correspond' ) {
+            $Ticket->Correspond( Content => $txn->Content );
+        }
+        elsif ( $txn->Type eq 'Comment' ) {
+            $Ticket->Comment( Content => $txn->Content );
+        }
+    }
+    else {
+        $RT::Logger->error( "failed to load transcaction $id: $msg" );
+    }
+}
+}
+</%INIT>
+
diff --git a/html/Callbacks/CloneTicket/Ticket/Elements/ShowTransaction/ModifyDisplay b/html/Callbacks/CloneTicket/Ticket/Elements/ShowTransaction/ModifyDisplay
new file mode 100644
index 0000000..4b9b77a
--- /dev/null
+++ b/html/Callbacks/CloneTicket/Ticket/Elements/ShowTransaction/ModifyDisplay
@@ -0,0 +1,37 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%#  Copyright (c) 2002-2003 Jesse Vincent <jesse at bestpractical.com>
+%#  
+%#  This program is free software; you can redistribute it and/or modify
+%#  it under the terms of version 2 of the GNU General Public License 
+%#  as published by the Free Software Foundation.
+%# 
+%#  A copy of that license should have arrived with this
+%#  software, but in any event can be snarfed from www.gnu.org.
+%# 
+%#  This program is distributed in the hope that it will be useful,
+%#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+%#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%#  GNU General Public License for more details.
+%# 
+%# END LICENSE BLOCK
+
+<%init>
+my $type = $Transaction->Type;
+return unless $type eq 'Create' || $type eq 'Correspond' || $type eq 'Comment';
+# only add to $titlebar_cmd when there's some cmds already
+if ( ref $titlebar_cmd && $$titlebar_cmd) {
+$$titlebar_cmd .= "[<a href=\"" . $RT::WebPath .
+'/Ticket/Clone/index.html'. "?TransactionId=". $Transaction->Id .
+"&Pretask=1" . "\">". loc('Pretask') . "</a>]";
+$$titlebar_cmd .= "[<a href=\"" . $RT::WebPath . '/Ticket/Clone/index.html'. "?TransactionId=". $Transaction->Id . "\">". loc('Clone') . "</a>]";
+$$titlebar_cmd .= "[<a href=\"" . $RT::WebPath .
+'/Ticket/Clone/index.html'. "?TransactionId=". $Transaction->Id .
+"&Posttask=1" . "\">". loc('Posttask') . "</a>]";
+}
+</%init>
+<%args>
+$titlebar_cmd => ''
+$Transaction
+</%args>
+
diff --git a/html/Callbacks/CloneTicket/Ticket/Elements/Tabs/Default b/html/Callbacks/CloneTicket/Ticket/Elements/Tabs/Default
new file mode 100644
index 0000000..d51ac32
--- /dev/null
+++ b/html/Callbacks/CloneTicket/Ticket/Elements/Tabs/Default
@@ -0,0 +1,42 @@
+%# BEGIN LICENSE BLOCK
+%# 
+%#  Copyright (c) 2002-2003 Jesse Vincent <jesse at bestpractical.com>
+%#  
+%#  This program is free software; you can redistribute it and/or modify
+%#  it under the terms of version 2 of the GNU General Public License 
+%#  as published by the Free Software Foundation.
+%# 
+%#  A copy of that license should have arrived with this
+%#  software, but in any event can be snarfed from www.gnu.org.
+%# 
+%#  This program is distributed in the hope that it will be useful,
+%#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+%#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%#  GNU General Public License for more details.
+%# 
+%# END LICENSE BLOCK
+
+<%init>
+if ($Ticket) {
+
+    my $path = 'Ticket/Clone/index.html?CloneTicket='. $Ticket->id;
+    $actions->{'0-Clone1'} = {
+        title => loc('Pretask'),
+        path => $path . '&Pretask=1',
+    };
+    $actions->{'0-Clone2'} = {
+        title => loc('Clone'),
+        path => $path,
+    };
+    $actions->{'0-Clone3'} = {
+        title => loc('Posttask'),
+        path => $path . '&Posttask=1',
+    };
+}
+
+</%init>
+<%args>
+$Ticket => undef
+$actions => undef
+</%args>
+
diff --git a/html/Ticket/Clone/index.html b/html/Ticket/Clone/index.html
new file mode 100644
index 0000000..83e464b
--- /dev/null
+++ b/html/Ticket/Clone/index.html
@@ -0,0 +1,216 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%# 
+%# COPYRIGHT:
+%#  
+%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC 
+%#                                          <jesse at bestpractical.com>
+%# 
+%# (Except where explicitly superseded by other copyright notices)
+%# 
+%# 
+%# LICENSE:
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%# 
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%# 
+%# 
+%# CONTRIBUTION SUBMISSION POLICY:
+%# 
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%# 
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%# 
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("[_1] Ticket #[_2]: [_3]",
+$clone_name, $CloneTicketObj->Id, $CloneTicketObj->Subject) &>
+<& /Ticket/Elements/Tabs, 
+    Ticket => $CloneTicketObj, 
+    current_tab => "Ticket/Clone/index.html?CloneTicket=".$CloneTicketObj->Id, 
+    Title => loc("[_1] Ticket #[_2]: [_3]", $clone_name, $CloneTicketObj->Id,
+$CloneTicketObj->Subject) &>
+
+<form method="post" action="<%$RT::WebPath%>/Ticket/Create.html" enctype="multipart/form-data">
+% for ( keys %ARGS ) {
+<input type="hidden" name="<%$_%>" value="<% $ARGS{$_} %>" />
+% }
+<input type="hidden" name="AddMoreAttach" value="1" />
+<input type="hidden" name="id" value="new" />
+<input type="hidden" name="Requestors" value="<% $session{CurrentUser}->EmailAddress %>" />
+% # from customer:
+% # Priority and timing information would be nice. (special starts, due for
+% # our calendering system)
+
+% # don't clone these fields
+% # TODO: need confirmation of this
+% for my $field ( qw/Owner TimeEstimated TimeWorked Status
+% TimeLeft Started Resolved Cc AdminCc/ ) {
+    <input type="hidden" name="<% $field %>" value="" />
+% }
+
+% for my $field ( 'RefersTo-new', 'new-RefersTo', 'new-DependsOn',
+% 'DependsOn-new', 'MemberOf-new', 'new-MemberOf' ) {
+% unless ( $ARGS{$field} ) {
+    <input type="hidden" name="<% $field %>" value="" />
+% }}
+
+% if ( @Transactions ) {
+    <input type="hidden" name="Transactions" value="<% join ',', @Transactions %>" />
+% }
+<table>
+<tr>
+<td><&|/l, $clone_name, $ARGS{CloneTicket} &>[_1] ticket [_2] in queue</&>:</td>
+<tr>
+<td>
+<select name="Queue" size="<% $queues_number %>">
+% for my $queue (@{$session{$cache_key}}) {
+  <option value="<% $queue->{Id} %>" 
+% if ($queue->{Id} eq $CloneTicketObj->Queue) {
+ selected="selected"
+% }
+>
+    <%$queue->{Name}%>
+
+% if ($queue->{Description}) {
+    (<%$queue->{Description}%>)
+% }
+  </option>
+%     }
+</select>
+</td>
+</tr>
+<table>
+<& /Elements/Submit, Label => loc('Next') &>
+
+</form>
+
+<%INIT>
+if ( $ARGS{TransactionId} ) {
+    my $txn = RT::Transaction->new( $session{CurrentUser} );
+    my ( $ret, $msg ) = $txn->Load( $ARGS{TransactionId} );
+    if ( $ret ) {
+        $ARGS{CloneTicket} = $txn->Ticket;
+        $ARGS{Content} = $txn->Content;
+    }
+    else {
+        RT::Logger->error( "can't load transaction $ARGS{'TransactionId'}: $msg" );
+        return;
+    }
+}
+
+my $CloneTicketObj = LoadTicket($ARGS{CloneTicket});
+my @Transactions;
+unless ( $ARGS{TransactionId} ) {
+    my $Transactions = $CloneTicketObj->Transactions;
+    while ( my $txn = $Transactions->Next ) {
+        if ( $txn->Type eq 'Create' || $txn->Type eq 'Correspond' || $txn->Type eq 'Comment' ) {
+            push @Transactions, $txn->id;
+        }
+    }
+}
+
+my $atts = $m->comp('/Ticket/Elements/FindAttachments', Ticket => $CloneTicketObj);
+$session{Attachments} = {};
+while ( my $att = $atts->Next ) {
+    next unless $att->Filename;
+    my $Message = MIME::Entity->build(
+        Type    => 'multipart/mixed',
+        Subject => $att->Subject,
+    );
+    $Message->attach(
+        Type     => $att->ContentType,
+        Filename => $att->Filename,
+        Data     => $att->Content,
+    );
+    $Message->make_singlepart;
+    $session{Attachments}{$att->Filename} = $Message;
+}
+
+if ( $ARGS{Pretask} ) {
+    $ARGS{Subject} = 'Pretask: ' . $CloneTicketObj->Subject;
+    $ARGS{'DependsOn-new'} = $CloneTicketObj->Id;
+}
+elsif ( $ARGS{Posttask} ) {
+    $ARGS{Subject} = 'Posttask: ' . $CloneTicketObj->Subject;
+    $ARGS{'new-DependsOn'} = $CloneTicketObj->Id;
+}
+else {
+    $ARGS{'RefersTo-new'} = $CloneTicketObj->Id;
+}
+
+# dump /Elements/SelectQueue: we need to make multiple queues visible
+my $cache_key = "SelectQueue---"
+                . $session{'CurrentUser'}->Id
+                . "---CreateTicket---1";
+
+if (not defined $session{$cache_key} ) {
+    my $q = new RT::Queues($session{'CurrentUser'});
+    $q->UnLimit;
+    
+    while (my $queue = $q->Next) {
+        if ($queue->CurrentUserHasRight('CreateTicket')) {
+            push @{$session{$cache_key}}, {
+                Id          => $queue->Id,
+                Name        => $queue->Name,
+                Description => $queue->Description,
+            };
+        }
+    }
+}
+my $queues_number = @{$session{$cache_key}};
+my $clone_name = $ARGS{Pretask} ? 'Pretask' : $ARGS{Posttask} ? 'Posttask' : 'Clone';
+
+if ( $ARGS{Queue} ) {
+    my $query = '';
+    for my $field ( keys %ARGS ) {
+        RT::Interface::Web::EscapeURI(\$ARGS{$field});
+        $query .= "$field=" . $ARGS{$field} . '&';
+    }
+    $query .= 'AddMoreAttach=1&id=new&';
+    $query .= 'Requestors=' . $session{CurrentUser}->EmailAddress . '&';
+    for my $field ( qw/Owner TimeEstimated TimeWorked Status
+        TimeLeft Started Resolved Cc AdminCc/ ) {
+        $query .= "$field=&"; # empty value
+    }
+
+    for my $field ( 'RefersTo-new', 'new-RefersTo', 'new-DependsOn',
+        'DependsOn-new', 'MemberOf-new', 'new-MemberOf' ) {
+        unless ( $ARGS{$field} ) {
+            $query .= "$field=&";
+        }
+    }
+
+    $query .= "Transactions=" . join ',', @Transactions;
+    my ( $minor_version ) = $RT::VERSION =~ /3.(\d)/;
+    if ( $minor_version >= 8 ) {
+        RT::Interface::Web::Redirect( RT->Config->Get('WebURL') . "Ticket/Create.html?$query" );
+    }
+    else {
+        RT::Interface::Web::Redirect( $RT::WebURL . "Ticket/Create.html?$query" );
+    }
+}
+</%INIT>
+
diff --git a/lib/RT/Extension/CloneTicket/WithData.pm b/lib/RT/Extension/CloneTicket/WithData.pm
new file mode 100644
index 0000000..4f10af4
--- /dev/null
+++ b/lib/RT/Extension/CloneTicket/WithData.pm
@@ -0,0 +1,9 @@
+package RT::Extension::CloneTicket::WithData;
+
+use warnings;
+use strict;
+our $VERSION = '0.07';
+
+
+1;
+
diff --git a/patch_on_3.6.5 b/patch_on_3.6.5
new file mode 100644
index 0000000..ea18a2f
--- /dev/null
+++ b/patch_on_3.6.5
@@ -0,0 +1,213 @@
+--- share/html/Elements/EditCustomFieldBinary	(revision 21664)
++++ share/html/Elements/EditCustomFieldBinary	(local)
+@@ -45,6 +45,14 @@
+ %# those contributions and any derivatives thereof.
+ %# 
+ %# END BPS TAGGED BLOCK }}}
++% if ( $m->callers(-2) && $m->callers(-2)->path eq '/Ticket/Create.html' && $session{CloneCustomField} && $session{CloneCustomField}{$CustomField->Id} ) {
++%    for my $value ( @{$session{CloneCustomField}{$CustomField->Id}} ) {
++<input type="checkbox" class="checkbox"
++    name="<%$NamePrefix%><%$CustomField->Id%>-DeleteCloneValueIds"
++    class="CF-<%$CustomField->id%>-Edit" value="<% $value->{Id} %>"/>
++    <% $value->{Value} %><br />
++%    }
++% }
+ % while ($Values and my $value = $Values->Next ) {
+ %# XXX - let user download the file(s) here?
+ <input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteValueIds" value="<% $value->Id %>" /><a href="<%$RT::WebPath%>/Download/CustomFieldValue/<% $value->Id %>/<% $value->Content %>"><% $value->Content %></a><br />
+--- share/html/Elements/EditCustomFieldImage	(revision 21664)
++++ share/html/Elements/EditCustomFieldImage	(local)
+@@ -45,6 +45,13 @@
+ %# those contributions and any derivatives thereof.
+ %# 
+ %# END BPS TAGGED BLOCK }}}
++% if ( $m->callers(-2) && $m->callers(-2)->path eq '/Ticket/Create.html' && $session{CloneCustomField} && $session{CloneCustomField}{$CustomField->Id} ) {
++%    for my $value ( @{$session{CloneCustomField}{$CustomField->Id}} ) {
++<input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteCloneValueIds" class="CF-<%$CustomField->id%>-Edit" value="<% $value->{Id} %>"/>
++    <% $value->{Value} %><br />
++%    }
++% }
++
+ % while ($Values and my $value = $Values->Next ) {
+ <input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteValueIds" value="<% $value->Id %>" /><& ShowCustomFieldImage, Object => $value &>
+ <br />
+--- share/html/Elements/MessageBox	(revision 21664)
++++ share/html/Elements/MessageBox	(local)
+@@ -46,6 +46,7 @@
+ %# 
+ %# END BPS TAGGED BLOCK }}}
+ <textarea class="messagebox" cols="<%$Width%>" rows="<%$Height%>" wrap="<%$Wrap%>" name="<%$Name%>"><& /Elements/Callback, %ARGS &><% $Default %><%$message%><%$IncludeSignature ? $signature : ''%></textarea>
++<&/Elements/Callback,_CallbackName => 'AfterTextArea', %ARGS&>
+ <%INIT>
+ 
+ my $message = '';
+--- share/html/Ticket/Create.html	(revision 21664)
++++ share/html/Ticket/Create.html	(local)
+@@ -239,7 +239,92 @@
+ </form>
+ 
+ <%INIT>
++$m->comp( '/Elements/Callback', _CallbackName => 'Init',ARGSRef =>\%ARGS );
++my $CloneTicketObj;
++if ( $CloneTicket ) {
++    $CloneTicketObj = RT::Ticket->new( $session{CurrentUser} );
++    $CloneTicketObj->Load($CloneTicket) or Abort(loc("Ticket could not be loaded"));
++    
++    my $clone = {
++        Requestors       => join( ',', $CloneTicketObj->RequestorAddresses ),
++        Cc               => join( ',', $CloneTicketObj->CcAddresses),
++        AdminCc          => join( ',', $CloneTicketObj->AdminCcAddresses),
++        InitialPriority => $CloneTicketObj->Priority, 
++    };
++    
++    $clone->{$_} = $CloneTicketObj->$_() 
++        for qw/Owner Subject FinalPriority TimeEstimated TimeWorked 
++                Status TimeLeft Starts Started Due Resolved/;
++    
++        my $members = $CloneTicketObj->Members;
++        my ( @members, @members_of, @refers, @refers_by, @depends, @depends_by );
++        while ( my $member = $members->Next ) {
++            push @members, $member->LocalBase;
++        }
++        $clone->{'MemberOf-new'} = join ' ', @members;
++    
++        my $members_of = $CloneTicketObj->MemberOf;
++        while ( my $member_of = $members_of->Next ) {
++            push @members_of, $member_of->LocalTarget;
++        }
++        $clone->{'new-MemberOf'} = join ' ', @members_of;
++        
++        my $refers = $CloneTicketObj->RefersTo;
++        while ( my $refer = $refers->Next ) {
++            push @refers, $refer->LocalTarget;
++        }
++        $clone->{'new-RefersTo'} = join ' ', @refers;
++    
++        my $refers_by = $CloneTicketObj->ReferredToBy;
++        while ( my $refer_by = $refers_by->Next ) {
++            push @refers_by, $refer_by->LocalBase;
++        }
++        $clone->{'RefersTo-new'} = join ' ', @refers_by;
++    
++        my $depends = $CloneTicketObj->DependsOn;
++        while ( my $depend = $depends->Next ) {
++            push @depends, $depend->LocalTarget;
++        }
++        $clone->{'new-DependsOn'} = join ' ', @depends;
++    
++        my $depends_by = $CloneTicketObj->DependedOnBy;
++        while ( my $depend_by = $depends_by->Next ) {
++            push @depends_by, $depend_by->LocalBase;
++        }
++        $clone->{'DependsOn-new'} = join ' ', @depends_by;
++    
++    
++    
++    my $cfs = $CloneTicketObj->QueueObj->TicketCustomFields();
++    while ( my $cf = $cfs->Next ) {
++        my $cf_id = $cf->id;
++        my $cf_values = $CloneTicketObj->CustomFieldValues( $cf->id );
++        my @cf_values;
++        while ( my $cf_value = $cf_values->Next ) {
++            push @cf_values, $cf_value->Content;
++        }
++        $clone->{"Object-RT::Ticket--CustomField-$cf_id-Value"} 
++            = join "\n", @cf_values;
++    }
++    
++    for ( keys %$clone ) {
++        $ARGS{$_} = $clone->{$_} if not defined $ARGS{$_};
++    }
++
++} 
+ 
++if ( $session{CloneCustomField} ) {
++    for my $cf_id ( keys %{$session{CloneCustomField}} ) {
++        my $delete = delete 
++            $ARGS{"Object-RT::Ticket--CustomField-$cf_id-DeleteCloneValueIds"};
++        my $values = $session{CloneCustomField}{$cf_id} || [];
++        for my $delete_id ( ref $delete ? @$delete : $delete ) {
++            @$values = grep { $_->{Id} ne $delete_id } @$values;
++        }
++        $ARGS{"Object-RT::Ticket--CustomField-$cf_id-Value"} = $values
++            if @$values;
++    }
++}
+ 
+ my @results;
+ my $QueueObj = new RT::Queue($session{'CurrentUser'});
+@@ -300,6 +385,7 @@
+ 
+ if ((!exists $ARGS{'AddMoreAttach'}) and ($ARGS{'id'} eq 'new')) { # new ticket?
+     if ($ValidCFs) {
++        delete $session{CloneCustomField};
+         $m->comp('Display.html', %ARGS);
+         $RT::Logger->crit("After display call; error is $@");
+         $m->abort();
+@@ -329,4 +415,5 @@
+ $MemberOf => undef
+ $QuoteTransaction => undef
+ $Queue => undef
++$CloneTicket => undef
+ </%ARGS>
+--- share/html/Ticket/Elements/ShowTransaction	(revision 21664)
++++ share/html/Ticket/Elements/ShowTransaction	(local)
+@@ -54,7 +54,8 @@
+     </td>
+     <td class="date"><% $transdate|n %></td>
+ % my $desc = $Transaction->BriefDescription;
+-% $m->comp('/Elements/Callback', _CallbackName => 'ModifyDisplay', text => \$desc, Transaction => $Transaction, %ARGS);
++% $m->comp('/Elements/Callback', _CallbackName => 'ModifyDisplay', text =>
++% \$desc, Transaction => $Transaction, titlebar_cmd => \$titlebar_commands, %ARGS);
+     <td class="description">
+       <%$Transaction->CreatorObj->Name%> - <%$TicketString%> <%$desc%>
+     </td>
+@@ -139,7 +140,7 @@
+ unless ($Attachments) { 
+     my $attachments = $Transaction->Attachments;
+     $attachments->Columns( qw( Id Filename ContentType Headers Subject Parent ContentEncoding ContentType TransactionId) );
+-    $Attachments = $attachments->ItemsArrayRef();
++    $ARGS{Attachments} = $Attachments = $attachments->ItemsArrayRef();
+ }
+ my $titlebar_commands = ' ';
+ 
+--- lib/RT/Interface/Web.pm	(revision 21664)
++++ lib/RT/Interface/Web.pm	(local)
+@@ -387,7 +387,9 @@
+     # XXX: workaround for name conflict :(
+     $create_args{'Requestor'} = delete $create_args{'Requestors'};
+ 
+-    foreach my $arg (keys %ARGS) {
++    # make *-Upload fields the last ones to handle
++    foreach my $arg ( sort { $a =~ /-Upload/ ? $b =~ /-Upload/ ? 0 : 1 : -1 }
++        keys %ARGS ) {
+         next if $arg =~ /-(?:Magic|Category)$/;
+ 
+         if ($arg =~ /^Object-RT::Transaction--CustomField-/) {
+@@ -408,12 +410,24 @@
+                 $ARGS{$arg} =~ s/\r//g;
+             }
+ 
++            my @values;
+             if ( $arg =~ /-Upload$/ ) {
+-                $create_args{"CustomField-".$cfid} = _UploadedFile($arg);
++                push @values, _UploadedFile($arg);
+             }
+             else {
+-                $create_args{"CustomField-".$cfid} = $ARGS{"$arg"};
++                @values =
++                  ref $ARGS{"$arg"} eq 'ARRAY'
++                  ? @{ $ARGS{$arg} }
++                  : $ARGS{$arg};
+             }
++
++            my $old_value = $create_args{"CustomField-$cfid"};
++            $create_args{"CustomField-$cfid"} =
++                defined $old_value
++              ? ref $old_value eq 'ARRAY'
++                  ? [ @$old_value, @values ]
++                  : [ $old_value, @values ]
++              : \@values;
+         }
+     }
+ 
diff --git a/patch_on_3.8 b/patch_on_3.8
new file mode 100644
index 0000000..5f985cd
--- /dev/null
+++ b/patch_on_3.8
@@ -0,0 +1,155 @@
+--- lib/RT/Interface/Web.pm	(revision 21664)
++++ lib/RT/Interface/Web.pm	(local)
+@@ -511,48 +511,60 @@
+         );
+     }
+ 
+-    foreach my $arg (keys %ARGS) {
++    # make *-Upload fields the last ones to handle
++    foreach my $arg ( sort { $a =~ /-Upload/ ? $b =~ /-Upload/ ? 0 : 1 : -1 }
++        keys %ARGS )
++    {
+         next if $arg =~ /-(?:Magic|Category)$/;
+ 
+-        if ($arg =~ /^Object-RT::Transaction--CustomField-/) {
++        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->Load( $cfid );
++            $cf->Load($cfid);
+             unless ( $cf->id ) {
+-                $RT::Logger->error( "Couldn't load custom field #". $cfid );
++                $RT::Logger->error( "Couldn't load custom field #" . $cfid );
+                 next;
+             }
+ 
++            my @values = ();
+             if ( $arg =~ /-Upload$/ ) {
+-                $create_args{"CustomField-$cfid"} = _UploadedFile( $arg );
+-                next;
++                push @values, _UploadedFile($arg);
+             }
++            else {
+ 
+-            my $type = $cf->Type;
++                my $type = $cf->Type;
+ 
+-            my @values = ();
+-            if ( ref $ARGS{ $arg } eq 'ARRAY' ) {
+-                @values = @{ $ARGS{ $arg } };
+-            } elsif ( $type =~ /text/i ) {
+-                @values = ($ARGS{ $arg });
+-            } else {
+-                @values = split /\r*\n/, $ARGS{ $arg } || '';
+-            }
+-            @values = grep length,
+-                map {
++                if ( ref $ARGS{$arg} eq 'ARRAY' ) {
++                    @values = @{ $ARGS{$arg} };
++                }
++                elsif ( $type =~ /text/i ) {
++                    @values = ( $ARGS{$arg} );
++                }
++                else {
++                    @values = split /\r*\n/, $ARGS{$arg} || '';
++                }
++                @values = grep length, map {
+                     s/\r+\n/\n/g;
+                     s/^\s+//;
+                     s/\s+$//;
+                     $_;
+-                }
+-                grep defined, @values;
++                  }
++                  grep defined, @values;
++            }
+ 
+-            $create_args{"CustomField-$cfid"} = \@values;
++            my $old_value = $create_args{"CustomField-$cfid"};
++            $create_args{"CustomField-$cfid"} =
++                defined $old_value
++              ? ref $old_value eq 'ARRAY'
++                  ? [ @$old_value, @values ]
++                  : [ $old_value, @values ]
++              : \@values;
+         }
+     }
+ 
+--- share/html/Elements/EditCustomFieldBinary	(revision 21664)
++++ share/html/Elements/EditCustomFieldBinary	(local)
+@@ -45,10 +45,19 @@
+ %# those contributions and any derivatives thereof.
+ %# 
+ %# END BPS TAGGED BLOCK }}}
++% if ( $m->callers(-2) && $m->callers(-2)->path eq '/Ticket/Create.html' && $session{CloneCustomField} && $session{CloneCustomField}{$CustomField->Id} ) {
++%    for my $value ( @{$session{CloneCustomField}{$CustomField->Id}} ) {
++<input type="checkbox" class="checkbox"
++    name="<%$NamePrefix%><%$CustomField->Id%>-DeleteCloneValueIds"
++    class="CF-<%$CustomField->id%>-Edit" value="<% $value->{Id} %>"/>
++    <% $value->{Value} %><br />
++%    }
++% }
+ % while ( $Values and my $value = $Values->Next ) {
+ %# XXX - let user download the file(s) here?
+ <input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteValueIds" class="CF-<%$CustomField->id%>-Edit" value="<% $value->Id %>" /><a href="<%RT->Config->Get('WebPath')%>/Download/CustomFieldValue/<% $value->Id %>/<% $value->Content %>"><% $value->Content %></a><br />
+ % }
++
+ % if (!$MaxValues || !$Values || $Values->Count < $MaxValues) {
+ <input type="file" name="<% $NamePrefix %><% $CustomField->Id %>-Upload" class="CF-<%$CustomField->id%>-Edit" />
+ % }
+--- share/html/Elements/EditCustomFieldImage	(revision 21664)
++++ share/html/Elements/EditCustomFieldImage	(local)
+@@ -45,6 +45,13 @@
+ %# those contributions and any derivatives thereof.
+ %# 
+ %# END BPS TAGGED BLOCK }}}
++% if ( $m->callers(-2) && $m->callers(-2)->path eq '/Ticket/Create.html' && $session{CloneCustomField} && $session{CloneCustomField}{$CustomField->Id} ) {
++%    for my $value ( @{$session{CloneCustomField}{$CustomField->Id}} ) {
++<input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteCloneValueIds" class="CF-<%$CustomField->id%>-Edit" value="<% $value->{Id} %>"/>
++    <% $value->{Value} %><br />
++%    }
++% }
++
+ % while ($Values and my $value = $Values->Next ) {
+ <input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteValueIds" class="CF-<%$CustomField->id%>-Edit" value="<% $value->Id %>" /><& ShowCustomFieldImage, Object => $value &>
+ <br />
+--- share/html/Ticket/Create.html	(revision 21664)
++++ share/html/Ticket/Create.html	(local)
+@@ -319,9 +319,23 @@
+     for ( keys %$clone ) {
+         $ARGS{$_} = $clone->{$_} if not defined $ARGS{$_};
+     }
++}
+ 
++if ( $session{CloneCustomField} ) {
++    for my $cf_id ( keys %{$session{CloneCustomField}} ) {
++        my $delete = delete 
++            $ARGS{"Object-RT::Ticket--CustomField-$cf_id-DeleteCloneValueIds"};
++        my $values = $session{CloneCustomField}{$cf_id} || [];
++        for my $delete_id ( ref $delete ? @$delete : $delete ) {
++            @$values = grep { $_->{Id} ne $delete_id } @$values;
++        }
++        $ARGS{"Object-RT::Ticket--CustomField-$cf_id-Value"} = $values
++            if @$values;
++    }
+ }
++
+ my @results;
++
+ my $QueueObj = new RT::Queue($session{'CurrentUser'});
+ $QueueObj->Load($Queue) || Abort(loc("Queue could not be loaded."));
+ 
+@@ -389,6 +403,7 @@
+ 
+ if ((!exists $ARGS{'AddMoreAttach'}) and (defined($ARGS{'id'}) and $ARGS{'id'} eq 'new')) { # new ticket?
+     if ( $ValidCFs && !$checks_failure && !$skip_create ) {
++        delete $session{CloneCustomField};
+         $m->comp('Display.html', %ARGS);
+         $RT::Logger->crit("After display call; error is $@");
+         $m->abort();

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



More information about the Bps-public-commit mailing list