%# BEGIN BPS TAGGED BLOCK {{{ %# %# COPYRIGHT: %# %# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC %# %# %# (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 }}} <%PERL> # Find all the attachments which have parent $Parent # For each of these attachments foreach my $message ( @{ $Attachments->{ $Parent || 0 } || [] } ) { $m->comp( 'ShowMessageHeaders', WarnUnsigned => $WarnUnsigned, Message => $message, DisplayHeaders => \@DisplayHeaders, ); my $name = defined $message->Filename && length $message->Filename ? $message->Filename : ''; my $should_render_download = $message->ContentLength || $name; $m->callback(CallbackName => 'BeforeAttachment', ARGSRef => \%ARGS, Object => $Object, Transaction => $Transaction, Attachment => $message, Name => $name, ShouldRenderDownload => \$should_render_download); if ($should_render_download) {
<&|/l&>Download <% length $name ? $name : loc('(untitled)') %>\ % if ( $DownloadableHeaders && ! length $name && $message->ContentType =~ /text/ ) { / <% loc('with headers') %> % } % $m->callback(CallbackName => 'AfterDownloadLinks', ARGSRef => \%ARGS, Object => $Object, Transaction => $Transaction, Attachment => $message);
<% $message->ContentType %> <% $message->FriendlyContentLength %>
% } %# If there is sub-messages, open a dedicated div % if ( $Attachments->{ $message->id } ) {
% } else {
% } <%PERL> $render_attachment->( $message ); $m->comp( $m->current_comp, %ARGS, Parent => $message->id, ParentObj => $message, displayed_inline => $displayed_inline, );
% } <%ARGS> $Transaction $Object => $Transaction->Object $ShowHeaders => 0 $DownloadableHeaders => 1 $AttachmentPath => undef $Attachments => {} $AttachmentContent => {} $Parent => 0 $ParentObj => undef $WarnUnsigned => 0 # Keep track of CID images we display inline $displayed_inline => {} <%INIT> my @DisplayHeaders=qw(_all); if ( $Transaction->Type =~ /EmailRecord$/ ) { @DisplayHeaders = qw(To Cc Bcc); } # If the transaction has anything attached to it at all elsif (!$ShowHeaders) { @DisplayHeaders = qw(To From RT-Send-Cc Cc Bcc Date Subject); push @DisplayHeaders, 'RT-Send-Bcc' if RT->Config->Get('ShowBccHeader'); } $m->callback(CallbackName => 'MassageDisplayHeaders', DisplayHeaders => \@DisplayHeaders, Transaction => $Transaction, ShowHeaders => $ShowHeaders); my $render_attachment = sub { my $message = shift; my $name = defined $message->Filename && length $message->Filename ? $message->Filename : ''; my $content_type = lc $message->ContentType; # if it has a content-disposition: attachment, don't show inline my $disposition = $message->GetHeader('Content-Disposition'); if ( $disposition && $disposition =~ /^\s*attachment/i ) { $disposition = 'attachment'; } else { $disposition = 'inline'; } # If it's text if ( $content_type =~ m{^(text|message)/} ) { my $max_size = RT->Config->Get( 'MaxInlineBody', $session{'CurrentUser'} ); if ( $disposition ne 'inline' ) { $m->out('

'. loc( 'Message body is not shown because sender requested not to inline it.' ) .'

'); return; } elsif ( length $name && RT->Config->Get('SuppressInlineTextFiles', $session{'CurrentUser'} ) ) { $m->out('

'. loc( 'Text file is not shown because it is disabled in preferences.' ) .'

'); return; } elsif ( $max_size && $message->ContentLength > $max_size ) { $m->out('

'. loc( 'Message body is not shown because it is too large.' ) .'

'); return; } if ( # it's a toplevel object !$ParentObj # or its parent isn't a multipart alternative || ( $ParentObj->ContentType !~ m{^multipart/(?:alternative|related)$}i ) # or it's of our prefered alterative type || ( ( RT->Config->Get('PreferRichText', $session{CurrentUser}) && ( $content_type =~ m{^text/(?:html|enriched)$} ) ) || ( !RT->Config->Get('PreferRichText', $session{CurrentUser}) && ( $content_type !~ m{^text/(?:html|enriched)$} ) ) ) ) { my $content; # If we've cached the content, use it from there if (my $x = $AttachmentContent->{ $Transaction->id }->{$message->id}) { $content = $x->Content; } else { $content = $message->Content; } $RT::Logger->debug( "Rendering attachment #". $message->id ." of '$content_type' type" ); # if it's a text/html clean the body and show it if ( $content_type eq 'text/html' ) { $content = $m->comp( '/Elements/ScrubHTML', Content => $content ); if (RT->Config->Get('ShowTransactionImages')) { my @rewritten = RT::Interface::Web::RewriteInlineImages( Content => \$content, Attachment => $message, # Not technically correct to search all parts of the # MIME structure, but it saves having to go to the # database again and is unlikely to break display. Related => [ map { @$_ } values %$Attachments ], AttachmentPath => $AttachmentPath, ); $displayed_inline->{$_}++ for @rewritten; } $m->comp( '/Elements/MakeClicky', content => \$content, html => 1, object => $Object, ); if ( !length $name && RT->Config->Get( 'QuoteFolding', $session{CurrentUser} ) ) { eval { require HTML::Quoted; $content = HTML::Quoted->extract($content) }; if ($@) { RT->Logger->error( "HTML::Quoted couldn't process attachment #@{[$message->id]}: $@." . " This is a bug, please report it to rt-bugs\@bestpractical.com."); } } $m->comp( 'ShowMessageStanza', Message => $content, Transaction => $Transaction, ContentType => 'text/html', ); } elsif ( $content_type eq 'text/enriched' ) { $content = $m->comp( '/Elements/ScrubHTML', Content => $content ); $m->out( $content ); } # It's a text type we don't have special handling for else { if ( !length $name && RT->Config->Get( 'QuoteFolding', $session{CurrentUser} ) ) { eval { require Text::Quoted; Text::Quoted::set_quote_characters(undef); $content = Text::Quoted::extract($content); }; if ($@) { RT->Logger->error( "Text::Quoted couldn't process attachment #@{[$message->id]}: $@." . " This is a bug, please report it to rt-bugs\@bestpractical.com."); } } $m->comp( 'ShowMessageStanza', Message => $content, Transaction => $Transaction, ContentType => 'text/plain', ); } } } # if it's an image, show it as an image elsif ( $content_type =~ m{^image/} ) { if (not RT->Config->Get('ShowTransactionImages')) { $m->out('

'. loc( 'Image not shown because display is disabled in system configuration.' ) .'

'); return; } elsif ( $displayed_inline->{$message->Id} ) { $m->out('

'. loc( 'Image displayed inline above' ) .'

'); return; } elsif ( $disposition ne 'inline' ) { $m->out('

'. loc( 'Image not shown because sender requested not to inline it.' ) .'

'); return; } my $filename = length $name ? $name : loc('(untitled)'); my $efilename = $m->interp->apply_escapes( $filename, 'h' ); $m->out( qq{$efilename' ); } elsif ( $message->ContentLength && $message->ContentLength > 0 ) { $m->out( '

' . loc( 'Message body not shown because it is not plain text.' ) . '

' ); } };