From 33fd4fb4815b38b7b4864a314da07fd66ca7b9e2 Mon Sep 17 00:00:00 2001 From: Matt Phillips Date: Thu, 19 May 2011 12:48:23 -0400 Subject: [PATCH 1/2] Fixed multipart/alternative MIME nesting with attachments --- lib/Email/Stuff.pm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/Email/Stuff.pm b/lib/Email/Stuff.pm index 8d2c10e..9ccd970 100644 --- a/lib/Email/Stuff.pm +++ b/lib/Email/Stuff.pm @@ -505,9 +505,18 @@ sub email { my @parts = $self->parts; ### Lyle Hopkins, code added to Fix single part, and multipart/alternative problems + # fixed multi attachment mixed/alternative MIME nesting -- mattp@cpan if ( scalar( @{ $self->{parts} } ) >= 3 ) { - ## multipart/mixed - $self->{email}->parts_set( \@parts ); + # $self->{email} is multipart/mixed, let the text/html body + # be in a nested multipart/alternative MIME object. + my $mp_alt = Email::MIME->create( + header => ['Content-Type' => 'multipart/alternative' ], + parts => [ $parts[0], $parts[1] ], + ); + + # take all other attachments and append them to the mp/alt MIME above + $self->{email}->parts_set( [ $mp_alt, @parts[2..$#parts] ] ); + } ## Check we actually have any parts elsif ( scalar( @{ $self->{parts} } ) ) { From adb7cfb47b80fab7a3b3de8ad3d42495405abf94 Mon Sep 17 00:00:00 2001 From: Matt Phillips Date: Thu, 19 May 2011 15:26:16 -0400 Subject: [PATCH 2/2] Fixed: restructured attachment handling --- lib/Email/Stuff.pm | 55 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/lib/Email/Stuff.pm b/lib/Email/Stuff.pm index 9ccd970..3b950c1 100644 --- a/lib/Email/Stuff.pm +++ b/lib/Email/Stuff.pm @@ -191,6 +191,7 @@ sub new { # mailer => undef, parts => [], email => Email::MIME->create( + attributes => { 'charset' => 'utf-8' }, header => [], parts => [], ), @@ -400,7 +401,7 @@ sub attach { # Determine the slot to put it at my $slot = scalar @{$self->{parts}}; - $slot = 3 if $slot < 3; + $slot = 2 if $slot < 2; # Create the part in the attachment slot $self->{parts}->[$slot] = Email::MIME->create( @@ -502,37 +503,37 @@ Creates and returns the full L object for the email. sub email { my $self = shift; - my @parts = $self->parts; + my ($text, $html, @parts) = @{ $self->{parts} }; - ### Lyle Hopkins, code added to Fix single part, and multipart/alternative problems - # fixed multi attachment mixed/alternative MIME nesting -- mattp@cpan - if ( scalar( @{ $self->{parts} } ) >= 3 ) { - # $self->{email} is multipart/mixed, let the text/html body - # be in a nested multipart/alternative MIME object. - my $mp_alt = Email::MIME->create( - header => ['Content-Type' => 'multipart/alternative' ], - parts => [ $parts[0], $parts[1] ], - ); + if ( _INSTANCE($text, 'Email::MIME') && _INSTANCE($html, 'Email::MIME') ) { - # take all other attachments and append them to the mp/alt MIME above - $self->{email}->parts_set( [ $mp_alt, @parts[2..$#parts] ] ); + # if we have extra parts, nest a multipart/alt inside a multipart/mixed MIME + if (scalar @parts) { + ## multipart/alternative with attachments + my $mp_alt = Email::MIME->create( + header => ['Content-Type' => 'multipart/alternative' ], + parts => [ $text, $html ], + ); + + $self->{email}->parts_set( [ $mp_alt, @parts ] ); + } else { + + ## multipart/alternative + $self->{email}->header_set( 'Content-Type' => 'multipart/alternative' ); + $self->{email}->parts_set( [ $text, $html ] ); } - ## Check we actually have any parts - elsif ( scalar( @{ $self->{parts} } ) ) { - if ( _INSTANCE($parts[0], 'Email::MIME') && _INSTANCE($parts[1], 'Email::MIME') ) { - ## multipart/alternate - $self->{email}->header_set( 'Content-Type' => 'multipart/alternative' ); - $self->{email}->parts_set( \@parts ); - } - ## As @parts is $self->parts without the blanks, we only need check $parts[0] - elsif ( _INSTANCE($parts[0], 'Email::MIME') ) { - ## single part text/plain - _transfer_headers( $self->{email}, $parts[0] ); - $self->{email} = $parts[0]; - } - } + } + ## As @parts is $self->parts without the blanks, we only need check $parts[0] + elsif ( _INSTANCE($text, 'Email::MIME') ) { + + # note @parts will collapse if empty + $self->{email}->parts_set( [ $text, @parts ] ); + } + elsif ( _INSTANCE($html, 'Email::MIME') ) { + $self->{email}->parts_set( [ $html, @parts ] ); + } $self->{email}; }