[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