X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Flib%2FRT%2FInterface%2FEmail.pm;h=b9145d63ade11a42122eac51c6bdb38e6e3a7b9f;hb=43a06151e47d2c59b833cbd8c26d97865ee850b6;hp=9216887cddb801b87eb4880987b154d13527c26b;hpb=6587f6ba7d047ddc1686c080090afe7d53365bd4;p=freeside.git diff --git a/rt/lib/RT/Interface/Email.pm b/rt/lib/RT/Interface/Email.pm index 9216887cd..b9145d63a 100755 --- a/rt/lib/RT/Interface/Email.pm +++ b/rt/lib/RT/Interface/Email.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -387,7 +387,7 @@ sub SendEmail { unless ( $args{'Entity'}->head->get('Date') ) { require RT::Date; - my $date = RT::Date->new( $RT::SystemUser ); + my $date = RT::Date->new( RT->SystemUser ); $date->SetToNow; $args{'Entity'}->head->set( 'Date', $date->RFC2822( Timezone => 'server' ) ); } @@ -406,8 +406,10 @@ sub SendEmail { my $path = RT->Config->Get('SendmailPath'); my $args = RT->Config->Get('SendmailArguments'); - # SetOutgoingMailFrom - if ( RT->Config->Get('SetOutgoingMailFrom') ) { + # SetOutgoingMailFrom and bounces conflict, since they both want -f + if ( $args{'Bounce'} ) { + $args .= ' '. RT->Config->Get('SendmailBounceArguments'); + } elsif ( RT->Config->Get('SetOutgoingMailFrom') ) { my $OutgoingMailAddress; if ($TicketObj) { @@ -427,9 +429,6 @@ sub SendEmail { if $OutgoingMailAddress; } - # Set Bounce Arguments - $args .= ' '. RT->Config->Get('SendmailBounceArguments') if $args{'Bounce'}; - # VERP if ( $TransactionObj and my $prefix = RT->Config->Get('VERPPrefix') and @@ -555,7 +554,7 @@ sub PrepareEmailUsingTemplate { @_ ); - my $template = RT::Template->new( $RT::SystemUser ); + my $template = RT::Template->new( RT->SystemUser ); $template->LoadGlobalTemplate( $args{'Template'} ); unless ( $template->id ) { return (undef, "Couldn't load template '". $args{'Template'} ."'"); @@ -583,6 +582,7 @@ sub SendEmailUsingTemplate { Bcc => undef, From => RT->Config->Get('CorrespondAddress'), InReplyTo => undef, + ExtraHeaders => {}, @_ ); @@ -598,6 +598,9 @@ sub SendEmailUsingTemplate { $mail->head->set( $_ => Encode::encode_utf8( $args{ $_ } ) ) foreach grep defined $args{$_}, qw(To Cc Bcc From); + $mail->head->set( $_ => $args{ExtraHeaders}{$_} ) + foreach keys %{ $args{ExtraHeaders} }; + SetInReplyTo( Message => $mail, InReplyTo => $args{'InReplyTo'} ); return SendEmail( Entity => $mail ); @@ -615,7 +618,19 @@ sub ForwardTransaction { my $entity = $txn->ContentAsMIME; - return SendForward( %args, Entity => $entity, Transaction => $txn ); + 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 => '' @@ -635,13 +650,33 @@ sub ForwardTicket { ) for qw(Create Correspond); my $entity = MIME::Entity->build( - Type => 'multipart/mixed', + Type => 'multipart/mixed', + Description => 'forwarded ticket', ); $entity->add_part( $_ ) foreach map $_->ContentAsMIME, @{ $txns->ItemsArrayRef }; - return SendForward( %args, Entity => $entity, Ticket => $ticket, Template => 'Forward Ticket' ); + 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 => '' @@ -704,34 +739,52 @@ sub SendForward { $mail->head->set( $_ => EncodeToMIME( String => $args{$_} ) ) foreach grep defined $args{$_}, qw(To Cc Bcc); - $mail->attach( - Type => 'message/rfc822', - Disposition => 'attachment', - Description => 'forwarded message', - Data => $entity->as_string, - ); + $mail->make_multipart unless $mail->is_multipart; + $mail->add_part( $entity ); my $from; my $subject = ''; $subject = $txn->Subject if $txn; $subject ||= $ticket->Subject if $ticket; - if ( RT->Config->Get('ForwardFromUser') ) { - $from = ($txn || $ticket)->CurrentUser->UserObj->EmailAddress; - } else { + + unless ( RT->Config->Get('ForwardFromUser') ) { # XXX: what if want to forward txn of other object than ticket? $subject = AddSubjectTag( $subject, $ticket ); - $from = $ticket->QueueObj->CorrespondAddress - || RT->Config->Get('CorrespondAddress'); } + $mail->head->set( Subject => EncodeToMIME( String => "Fwd: $subject" ) ); - $mail->head->set( From => EncodeToMIME( String => $from ) ); + $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("Send email successfully")); + return (1, $ticket->loc("Sent email successfully")); +} + +=head2 GetForwardFrom Ticket => undef, Transaction => undef + +Resolve the From field to use in forward mail + +=cut + +sub GetForwardFrom { + 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->UserObj->EmailAddress; + } + else { + return $ticket->QueueObj->CorrespondAddress + || RT->Config->Get('CorrespondAddress'); + } } =head2 SignEncrypt Entity => undef, Sign => 0, Encrypt => 0 @@ -891,7 +944,7 @@ sub EncodeToMIME { return ($value); } - return ($value) unless $value =~ /[^\x20-\x7e]/; + return ($value) if $value =~ /^(?:[\t\x20-\x7e]|\x0D*\x0A[ \t])+$/s; $value =~ s/\s+$//; @@ -920,7 +973,7 @@ sub EncodeToMIME { sub CreateUser { my ( $Username, $Address, $Name, $ErrorsTo, $entity ) = @_; - my $NewUser = RT::User->new( $RT::SystemUser ); + my $NewUser = RT::User->new( RT->SystemUser ); my ( $Val, $Message ) = $NewUser->Create( Name => ( $Username || $Address ), @@ -955,7 +1008,7 @@ sub CreateUser { } #Load the new user object - my $CurrentUser = new RT::CurrentUser; + my $CurrentUser = RT::CurrentUser->new; $CurrentUser->LoadByEmail( $Address ); unless ( $CurrentUser->id ) { @@ -1087,12 +1140,7 @@ sub ParseAddressFromHeader { return ( undef, undef ); } - my $Name = ( $AddrObj->name || $AddrObj->phrase || $AddrObj->comment || $AddrObj->address ); - - #Lets take the from and load a user object. - my $Address = $AddrObj->address; - - return ( $Address, $Name ); + return ( $AddrObj->address, $AddrObj->phrase ); } =head2 DeleteRecipientsFromHead HEAD RECIPIENTS @@ -1195,7 +1243,7 @@ sub AddSubjectTag { my $subject = shift; my $ticket = shift; unless ( ref $ticket ) { - my $tmp = RT::Ticket->new( $RT::SystemUser ); + my $tmp = RT::Ticket->new( RT->SystemUser ); $tmp->Load( $ticket ); $ticket = $tmp; } @@ -1211,7 +1259,7 @@ sub AddSubjectTag { } return $subject if $subject =~ /\[$tag_re\s+#$id\]/; - $subject =~ s/(\r\n|\n|\s)/ /gi; + $subject =~ s/(\r\n|\n|\s)/ /g; chomp $subject; return "[". ($queue_tag || RT->Config->Get('rtname')) ." #$id] $subject"; } @@ -1263,7 +1311,7 @@ sub _LoadPlugins { } elsif ( !ref $plugin ) { my $Class = $plugin; $Class = "RT::Interface::Email::" . $Class - unless $Class =~ /^RT::Interface::Email::/; + unless $Class =~ /^RT::/; $Class->require or do { $RT::Logger->error("Couldn't load $Class: $@"); next }; @@ -1375,7 +1423,7 @@ sub Gateway { my $Subject = $head->get('Subject') || ''; chomp $Subject; - # {{{ Lets check for mail loops of various sorts. + # Lets check for mail loops of various sorts. my ($should_store_machine_generated_message, $IsALoop, $result); ( $should_store_machine_generated_message, $ErrorsTo, $result, $IsALoop ) = _HandleMachineGeneratedMail( @@ -1394,7 +1442,7 @@ sub Gateway { $args{'ticket'} ||= ParseTicketId( $Subject ); - $SystemTicket = RT::Ticket->new( $RT::SystemUser ); + $SystemTicket = RT::Ticket->new( RT->SystemUser ); $SystemTicket->Load( $args{'ticket'} ) if ( $args{'ticket'} ) ; if ( $SystemTicket->id ) { $Right = 'ReplyToTicket'; @@ -1403,7 +1451,7 @@ sub Gateway { } #Set up a queue object - my $SystemQueueObj = RT::Queue->new( $RT::SystemUser ); + my $SystemQueueObj = RT::Queue->new( RT->SystemUser ); $SystemQueueObj->Load( $args{'queue'} ); # We can safely have no queue of we have a known-good ticket @@ -1420,7 +1468,7 @@ sub Gateway { SystemQueue => $SystemQueueObj, ); - # {{{ If authentication fails and no new user was created, get out. + # If authentication fails and no new user was created, get out. if ( !$CurrentUser || !$CurrentUser->id || $AuthStat == -1 ) { # If the plugins refused to create one, they lose. @@ -1772,7 +1820,7 @@ sub _HandleMachineGeneratedMail { # Squelch replies if necessary # Don't let the user stuff the RT-Squelch-Replies-To header. if ( $head->get('RT-Squelch-Replies-To') ) { - $head->add( + $head->replace( 'RT-Relocated-Squelch-Replies-To', $head->get('RT-Squelch-Replies-To') ); @@ -1787,8 +1835,8 @@ sub _HandleMachineGeneratedMail { # to the scrip. We might want to notify nobody. Or just # the RT Owner. Or maybe all Privileged watchers. my ( $Sender, $junk ) = ParseSenderAddressFromHead($head); - $head->add( 'RT-Squelch-Replies-To', $Sender ); - $head->add( 'RT-DetectedAutoGenerated', 'true' ); + $head->replace( 'RT-Squelch-Replies-To', $Sender ); + $head->replace( 'RT-DetectedAutoGenerated', 'true' ); } return ( 1, $ErrorsTo, "Handled machine detection", $IsALoop ); }