Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

support customized forward message and use scrip to send forwarded me…

…ssage

now we record the forward transaction with customized message and use a scrip
bound to it to actually send the message.
(SendForward action is newly added for it)

As we use SendEmail action, invalid recipients will be stripped, so I removed
"rt-test" recipient in test.
  • Loading branch information...
commit ab8edd262c5741ea25f1ff521d6721d3f78fabd3 1 parent 62a4a2b
sunnavy sunnavy authored
19 etc/initialdata
View
@@ -98,6 +98,9 @@
{ Name => 'Extract Subject Tag', # loc
Description => 'Extract tags from a Transaction\'s subject and add them to the Ticket\'s subject.', # loc
ExecModule => 'ExtractSubjectTag' },
+ { Name => 'Send Forward', # loc
+ Description => 'Send forwarded message', # loc
+ ExecModule => 'SendForward', },
);
@ScripConditions = (
@@ -400,17 +403,21 @@ The ticket has been approved, you may now start to act on it.
},
{ Queue => 0,
Name => "Forward", # loc
- Description => "Heading of a forwarded message", # loc
+ Description => "Forwarded message", # loc
Content => q{
This is a forward of transaction #{$Transaction->id} of ticket #{ $Ticket->id }
+
+{ $ForwardTransaction->Content }
}
},
{ Queue => 0,
Name => "Forward Ticket", # loc
- Description => "Heading of a forwarded Ticket", # loc
+ Description => "Forwarded ticket message", # loc
Content => q{
This is a forward of ticket #{ $Ticket->id }
+
+{ $ForwardTransaction->Content }
}
},
{ Queue => 0,
@@ -555,6 +562,14 @@ Hour: { $SubscriptionObj->SubValue('Hour') }
ScripCondition => 'On Transaction',
ScripAction => 'Extract Subject Tag',
Template => 'Blank' },
+ { Description => 'On Forward Transaction Send forwarded message',
+ ScripCondition => 'On Forward Transaction',
+ ScripAction => 'Send Forward',
+ Template => 'Forward' },
+ { Description => 'On Forward Ticket Send forwarded message',
+ ScripCondition => 'On Forward Ticket',
+ ScripAction => 'Send Forward',
+ Template => 'Forward Ticket' },
);
@ACL = (
16 lib/RT/Action/SendEmail.pm
View
@@ -151,13 +151,15 @@ Builds an outgoing email we're going to send using scrip's template.
sub Prepare {
my $self = shift;
- my ( $result, $message ) = $self->TemplateObj->Parse(
- Argument => $self->Argument,
- TicketObj => $self->TicketObj,
- TransactionObj => $self->TransactionObj
- );
- if ( !$result ) {
- return (undef);
+ unless ( $self->TemplateObj->MIMEObj ) {
+ my ( $result, $message ) = $self->TemplateObj->Parse(
+ Argument => $self->Argument,
+ TicketObj => $self->TicketObj,
+ TransactionObj => $self->TransactionObj
+ );
+ if ( !$result ) {
+ return (undef);
+ }
}
my $MIMEObj = $self->TemplateObj->MIMEObj;
148 lib/RT/Action/SendForward.pm
View
@@ -0,0 +1,148 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# <sales@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/licenses/old-licenses/gpl-2.0.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 }}}
+
+#
+package RT::Action::SendForward;
+
+use strict;
+use warnings;
+
+use base qw(RT::Action::SendEmail);
+
+use Email::Address;
+
+=head2 Prepare
+
+=cut
+
+sub Prepare {
+ my $self = shift;
+
+ my $txn = $self->TransactionObj;
+
+ if ( $txn->Type eq 'Forward Transaction' ) {
+ my $forwarded_txn = RT::Transaction->new( $self->CurrentUser );
+ $forwarded_txn->Load( $txn->Field );
+ $self->{ForwardedTransactionObj} = $forwarded_txn;
+ }
+
+ my ( $result, $message ) = $self->TemplateObj->Parse(
+ Argument => $self->Argument,
+ Ticket => $self->TicketObj,
+ Transaction => $self->ForwardedTransactionObj,
+ ForwardTransaction => $self->TransactionObj,
+ );
+
+ if ( !$result ) {
+ return (undef);
+ }
+
+ my $mime = $self->TemplateObj->MIMEObj;
+ $mime->make_multipart unless $mime->is_multipart;
+
+ my $entity;
+ if ( $txn->Type eq 'Forward Transaction' ) {
+ $entity = $self->ForwardedTransactionObj->ContentAsMIME;
+ }
+ else {
+ my $txns = $self->TicketObj->Transactions;
+ $txns->Limit(
+ FIELD => 'Type',
+ VALUE => $_,
+ ) for qw(Create Correspond);
+
+ $entity = MIME::Entity->build(
+ Type => 'multipart/mixed',
+ Description => 'forwarded ticket',
+ );
+ $entity->add_part($_) foreach
+ map $_->ContentAsMIME,
+ @{ $txns->ItemsArrayRef };
+ }
+
+ $mime->add_part($entity);
+
+ unless ( $mime->head->get('Subject') ) {
+ my $subject = '';
+ $subject = $self->ForwardedTransactionObj->Subject
+ if $self->ForwardedTransactionObj;
+ $subject ||= $self->TicketObj->Subject;
+ unless ( RT->Config->Get('ForwardFromUser') ) {
+ $subject =
+ RT::Interface::Email::AddSubjectTag( $subject, $self->TicketObj );
+ }
+ $mime->head->set( Subject => $self->MIMEEncodeString("Fwd: $subject") );
+ }
+
+ my $txn_attachment = $self->TransactionObj->Attachments->First;
+ for my $header (qw/From To Cc Bcc/) {
+ if ( $txn_attachment->GetHeader( $header ) ) {
+ $mime->head->set( $header => $txn_attachment->GetHeader($header) );
+ }
+ }
+
+ if ( RT->Config->Get('ForwardFromUser') ) {
+ $mime->head->set( 'X-RT-Sign' => 0 );
+ }
+
+ $self->SUPER::Prepare();
+}
+
+sub SetSubjectToken {
+
+ # we already take care of this in Prepare.
+}
+
+sub ForwardedTransactionObj {
+ my $self = shift;
+ return $self->{'ForwardedTransactionObj'};
+}
+
+RT::Base->_ImportOverlays();
+
+1;
190 lib/RT/Interface/Email.pm
View
@@ -611,190 +611,56 @@ sub SendEmailUsingTemplate {
return SendEmail( Entity => $mail );
}
-=head2 ForwardTransaction TRANSACTION, To => '', Cc => '', Bcc => ''
-
-Forwards transaction with all attachments as 'message/rfc822'.
-
-=cut
-
-sub ForwardTransaction {
- my $txn = shift;
- my %args = ( To => '', Cc => '', Bcc => '', @_ );
-
- my $entity = $txn->ContentAsMIME;
-
- my ( $ret, $msg ) = SendForward( %args, Entity => $entity, Transaction => $txn );
- if ($ret) {
- my $ticket = $txn->TicketObj;
- my ( $ret, $msg ) = $ticket->_NewTransaction(
- Type => 'Forward Transaction',
- Field => $txn->id,
- Data => join ', ', grep { length } $args{To}, $args{Cc}, $args{Bcc},
- );
- unless ($ret) {
- $RT::Logger->error("Failed to create transaction: $msg");
- }
- }
- return ( $ret, $msg );
-}
-
-=head2 ForwardTicket TICKET, To => '', Cc => '', Bcc => ''
-
-Forwards a ticket's Create and Correspond Transactions and their Attachments as 'message/rfc822'.
-
-=cut
-
-sub ForwardTicket {
- my $ticket = shift;
- my %args = ( To => '', Cc => '', Bcc => '', @_ );
-
- my $txns = $ticket->Transactions;
- $txns->Limit(
- FIELD => 'Type',
- VALUE => $_,
- ) for qw(Create Correspond);
-
- my $entity = MIME::Entity->build(
- Type => 'multipart/mixed',
- Description => 'forwarded ticket',
- );
- $entity->add_part( $_ ) foreach
- map $_->ContentAsMIME,
- @{ $txns->ItemsArrayRef };
-
- my ( $ret, $msg ) = SendForward(
- %args,
- Entity => $entity,
- Ticket => $ticket,
- Template => 'Forward Ticket',
- );
-
- if ($ret) {
- my ( $ret, $msg ) = $ticket->_NewTransaction(
- Type => 'Forward Ticket',
- Field => $ticket->id,
- Data => join ', ', grep { length } $args{To}, $args{Cc}, $args{Bcc},
- );
- unless ($ret) {
- $RT::Logger->error("Failed to create transaction: $msg");
- }
- }
-
- return ( $ret, $msg );
-
-}
-
-=head2 SendForward Entity => undef, Ticket => undef, Transaction => undef, Template => undef, To => '', Cc => '', Bcc => ''
+=head2 GetForwardFrom Ticket => undef, Transaction => undef
-Forwards an Entity representing Ticket or Transaction as 'message/rfc822'. Entity is wrapped into Template.
+Resolve the From field to use in forward mail
=cut
-sub SendForward {
- my (%args) = (
- Entity => undef,
- Ticket => undef,
- Transaction => undef,
- Template => 'Forward',
- To => '', Cc => '', Bcc => '',
- @_
- );
-
- my $txn = $args{'Transaction'};
- my $ticket = $args{'Ticket'};
- $ticket ||= $txn->Object if $txn;
-
- my $entity = $args{'Entity'};
- unless ( $entity ) {
- require Carp;
- $RT::Logger->error(Carp::longmess("No entity provided"));
- return (0, $ticket->loc("Couldn't send email"));
- }
-
- my ($template, $msg) = PrepareEmailUsingTemplate(
- Template => $args{'Template'},
- Arguments => {
- Ticket => $ticket,
- Transaction => $txn,
- },
- );
-
- my $mail;
- if ( $template ) {
- $mail = $template->MIMEObj;
- } else {
- $RT::Logger->warning($msg);
- }
- unless ( $mail ) {
- $RT::Logger->warning("Couldn't generate email using template '$args{Template}'");
+sub GetForwardFrom {
+ my %args = ( Ticket => undef, Transaction => undef, @_ );
+ my $txn = $args{Transaction};
+ my $ticket = $args{Ticket} || $txn->Object;
- my $description;
- unless ( $args{'Transaction'} ) {
- $description = 'This is forward of ticket #'. $ticket->id;
- } else {
- $description = 'This is forward of transaction #'
- . $txn->id ." of a ticket #". $txn->ObjectId;
- }
- $mail = MIME::Entity->build(
- Type => 'text/plain',
- Data => $description,
- );
+ if ( RT->Config->Get('ForwardFromUser') ) {
+ return ( $txn || $ticket )->CurrentUser->EmailAddress;
}
-
- $mail->head->set( $_ => EncodeToMIME( String => $args{$_} ) )
- foreach grep defined $args{$_}, qw(To Cc Bcc);
-
- $mail->make_multipart unless $mail->is_multipart;
- $mail->add_part( $entity );
-
- my $from;
- unless (defined $mail->head->get('Subject')) {
- my $subject = '';
- $subject = $txn->Subject if $txn;
- $subject ||= $ticket->Subject if $ticket;
-
- unless ( RT->Config->Get('ForwardFromUser') ) {
- # XXX: what if want to forward txn of other object than ticket?
- $subject = AddSubjectTag( $subject, $ticket );
- }
-
- $mail->head->set( Subject => EncodeToMIME( String => "Fwd: $subject" ) );
+ else {
+ return $ticket->QueueObj->CorrespondAddress
+ || RT->Config->Get('CorrespondAddress');
}
-
- $mail->head->set(
- From => EncodeToMIME(
- String => GetForwardFrom( Transaction => $txn, Ticket => $ticket )
- )
- );
-
- my $status = RT->Config->Get('ForwardFromUser')
- # never sign if we forward from User
- ? SendEmail( %args, Entity => $mail, Sign => 0 )
- : SendEmail( %args, Entity => $mail );
- return (0, $ticket->loc("Couldn't send email")) unless $status;
- return (1, $ticket->loc("Sent email successfully"));
}
-=head2 GetForwardFrom Ticket => undef, Transaction => undef
+=head2 GetForwardAttachments Ticket => undef, Transaction => undef
-Resolve the From field to use in forward mail
+Resolve the Attachments to forward
=cut
-sub GetForwardFrom {
+sub GetForwardAttachments {
my %args = ( Ticket => undef, Transaction => undef, @_ );
my $txn = $args{Transaction};
my $ticket = $args{Ticket} || $txn->Object;
- if ( RT->Config->Get('ForwardFromUser') ) {
- return ( $txn || $ticket )->CurrentUser->EmailAddress;
+ my $attachments = RT::Attachments->new( $ticket->CurrentUser );
+ if ($txn) {
+ $attachments->Limit( FIELD => 'TransactionId', VALUE => $txn->id );
}
else {
- return $ticket->QueueObj->CorrespondAddress
- || RT->Config->Get('CorrespondAddress');
+ my $txns = $ticket->Transactions;
+ $txns->Limit(
+ FIELD => 'Type',
+ VALUE => $_,
+ ) for qw(Create Correspond);
+
+ while ( my $txn = $txns->Next ) {
+ $attachments->Limit( FIELD => 'TransactionId', VALUE => $txn->id );
+ }
}
+ return $attachments;
}
+
=head2 SignEncrypt Entity => undef, Sign => 0, Encrypt => 0
Signs and encrypts message using L<RT::Crypt::GnuPG>, but as well
69 lib/RT/Ticket.pm
View
@@ -3749,6 +3749,75 @@ sub ACLEquivalenceObjects {
}
+=head2 Forward Transaction => undef, To => '', Cc => '', Bcc => ''
+
+Forwards transaction with all attachments as 'message/rfc822'.
+
+=cut
+
+sub Forward {
+ my $self = shift;
+ my %args = (
+ Transaction => undef,
+ To => '',
+ Cc => '',
+ Bcc => '',
+ Content => '',
+ ContentType => 'text/plain',
+ DryRun => 0,
+ CommitScrips => 1,
+ @_
+ );
+
+ unless ( $self->CurrentUserHasRight('ForwardMessage') ) {
+ return ( 0, $self->loc("Permission Denied") );
+ }
+
+ my $mime = MIME::Entity->build(
+ Type => $args{'ContentType'},
+ Data => $args{Content},
+ );
+
+ $mime->head->set(
+ $_ => RT::Interface::Email::EncodeToMIME( String => $args{$_} ) )
+ for grep defined $args{$_}, qw(To Cc Bcc);
+ $mime->head->set(
+ From => RT::Interface::Email::EncodeToMIME(
+ String => RT::Interface::Email::GetForwardFrom(
+ Transaction => $args{Transaction},
+ Ticket => $self,
+ )
+ )
+ );
+
+ if ($args{'DryRun'}) {
+ $RT::Handle->BeginTransaction();
+ $args{'CommitScrips'} = 0;
+ }
+
+ my ( $ret, $msg ) = $self->_NewTransaction(
+ $args{Transaction}
+ ? (
+ Type => 'Forward Transaction',
+ Field => $args{Transaction}->id,
+ )
+ : (
+ Type => 'Forward Ticket',
+ Field => $self->id,
+ ),
+ MIMEObj => $mime,
+ CommitScrips => $args{'CommitScrips'},
+ );
+
+ unless ($ret) {
+ $RT::Logger->error("Failed to create transaction: $msg");
+ }
+
+ if ($args{'DryRun'}) {
+ $RT::Handle->Rollback();
+ }
+ return ( $ret, $self->loc('Message recorded') );
+}
1;
5 lib/RT/Transaction.pm
View
@@ -661,11 +661,10 @@ sub BriefDescription {
return $self->loc("System error");
}
elsif ( $type =~ /Forward Transaction/ ) {
- return $self->loc( "Forwarded Transaction #[_1] to [_2]",
- $self->Field, $self->Data );
+ return $self->loc( "Forwarded Transaction #[_1]", $self->Field );
}
elsif ( $type =~ /Forward Ticket/ ) {
- return $self->loc( "Forwarded Ticket to [_1]", $self->Data );
+ return $self->loc( "Forwarded Ticket" );
}
if ( my $code = $_BriefDescriptions{$type} ) {
23 share/html/Ticket/Forward.html
View
@@ -72,8 +72,21 @@
<tr><td align="right"><&|/l&>Bcc</&>:</td>
<td><input name="Bcc" size="60" value="<% $ARGS{'Bcc'} || '' %>" /></td></tr>
+<tr>
+<td><&|/l&>Content</&>:</td>
+<td>
+% if (exists $ARGS{Content}) {
+<& /Elements/MessageBox, Default => $ARGS{Content}, IncludeSignature => 0 &>
+% } else {
+<& /Elements/MessageBox &>
+%}
+</td>
+</tr>
+
</table>
+<& /Ticket/Elements/ShowAttachments, Attachments => $attachments &>
+
<& /Elements/Submit, Label => loc('Forward Message and Return'), Name => 'ForwardAndReturn' &>
<& /Elements/Submit, Label => loc('Forward Message'), Name => 'Forward' &>
</form>
@@ -94,10 +107,7 @@
my @results;
if ( $Forward || $ForwardAndReturn ) {
- require RT::Interface::Email;
- my ($status, $msg) = $txn
- ? RT::Interface::Email::ForwardTransaction( $txn, %ARGS )
- : RT::Interface::Email::ForwardTicket( $TicketObj, %ARGS );
+ my ( $status, $msg ) = $TicketObj->Forward( Transaction => $txn, %ARGS );
push @results, $msg;
if ( $ForwardAndReturn ) {
@@ -119,6 +129,11 @@
$subject = RT::Interface::Email::AddSubjectTag( $subject, $TicketObj )
unless RT->Config->Get('ForwardFromUser');
+my $attachments = RT::Interface::Email::GetForwardAttachments(
+ Ticket => $TicketObj,
+ $txn ? ( Transaction => $txn ) : (),
+);
+
</%INIT>
<%ARGS>
31 t/web/ticket_forward.t
View
@@ -37,18 +37,15 @@ diag "Forward Ticket" if $ENV{TEST_VERBOSE};
$m->submit_form(
form_name => 'ForwardMessage',
fields => {
- To => 'rt-test, rt-to@example.com',
+ To => 'rt-to@example.com',
Cc => 'rt-cc@example.com',
},
button => 'ForwardAndReturn'
);
- $m->content_contains( 'Sent email successfully', 'sent mail msg' );
- $m->content_contains(
- 'Forwarded Ticket to rt-test, rt-to@example.com, rt-cc@example.com',
- 'txn msg' );
+ $m->content_contains( 'Forwarded Ticket', 'txn msg' );
my ($mail) = RT::Test->fetch_caught_mails;
like( $mail, qr!Subject: test forward!, 'Subject field' );
- like( $mail, qr!To: rt-test, rt-to\@example.com!, 'To field' );
+ like( $mail, qr!To: rt-to\@example.com!, 'To field' );
like( $mail, qr!Cc: rt-cc\@example.com!, 'Cc field' );
like( $mail, qr!This is a forward of ticket!, 'content' );
like( $mail, qr!this is an attachment!, 'att content' );
@@ -61,20 +58,16 @@ diag "Forward Transaction" if $ENV{TEST_VERBOSE};
$m->submit_form(
form_name => 'ForwardMessage',
fields => {
- To => 'rt-test, rt-to@example.com',
+ To => 'rt-to@example.com',
Cc => 'rt-cc@example.com',
Bcc => 'rt-bcc@example.com'
},
button => 'ForwardAndReturn'
);
- $m->content_contains( 'Sent email successfully', 'sent mail msg' );
- $m->content_like(
-qr/Forwarded Transaction #\d+ to rt-test, rt-to\@example.com, rt-cc\@example.com, rt-bcc\@example.com/,
- 'txn msg'
- );
+ $m->content_like( qr/Forwarded Transaction #\d+/, 'txn msg' );
my ($mail) = RT::Test->fetch_caught_mails;
like( $mail, qr!Subject: test forward!, 'Subject field' );
- like( $mail, qr!To: rt-test, rt-to\@example.com!, 'To field' );
+ like( $mail, qr!To: rt-to\@example.com!, 'To field' );
like( $mail, qr!Cc: rt-cc\@example.com!, 'Cc field' );
like( $mail, qr!Bcc: rt-bcc\@example.com!, 'Bcc field' );
like( $mail, qr!This is a forward of transaction!, 'content' );
@@ -94,7 +87,6 @@ diag "Forward Ticket without content" if $ENV{TEST_VERBOSE};
fields => { To => 'rt-test@example.com', },
button => 'ForwardAndReturn'
);
- $m->content_contains( 'Sent email successfully', 'sent mail msg' );
my ($mail) = RT::Test->fetch_caught_mails;
like( $mail, qr/Subject: Fwd: \[example\.com #\d\] test forward without content/, 'Subject field' );
like( $mail, qr/To: rt-test\@example\.com/, 'To field' );
@@ -138,8 +130,7 @@ diag "Forward Transaction with attachments but empty content" if $ENV{TEST_VERBO
},
button => 'ForwardAndReturn'
);
- $m->content_contains( 'Sent email successfully', 'sent mail msg' );
- $m->content_like( qr/Forwarded Transaction #\d+ to rt-test\@example\.com/, 'txn msg' );
+ $m->content_like(qr/Forwarded Transaction #\d+/);
my ($mail) = RT::Test->fetch_caught_mails;
like( $mail, qr/Subject: test forward, empty content but attachments/, 'Subject field' );
like( $mail, qr/To: rt-test\@example.com/, 'To field' );
@@ -196,9 +187,8 @@ diag "Forward Transaction with attachments but no 'content' part" if $ENV{TEST_V
},
button => 'ForwardAndReturn'
);
- $m->content_contains( 'Sent email successfully', 'sent mail msg' );
- $m->content_like( qr/Forwarded Transaction #\d+ to rt-test\@example\.com/, 'txn msg' );
-
+ $m->content_like( qr/Forwarded Transaction #\d+/ );
+
# Forward ticket
$m->follow_link_ok( { text => 'Forward', n => 1 }, 'follow 1st Forward' );
$m->submit_form(
@@ -208,8 +198,7 @@ diag "Forward Transaction with attachments but no 'content' part" if $ENV{TEST_V
},
button => 'ForwardAndReturn'
);
- $m->content_contains( 'Sent email successfully', 'sent mail msg' );
- $m->content_like( qr/Forwarded Ticket to rt-test\@example\.com/, 'txn msg' );
+ $m->content_like( qr/Forwarded Ticket/ );
my ($forward_txn, $forward_ticket) = RT::Test->fetch_caught_mails;
my $tag = qr/Fwd: \[example\.com #\d+\]/;
Please sign in to comment.
Something went wrong with that request. Please try again.