File Coverage

blib/lib/Mail/Message/Construct/Forward.pm
Criterion Covered Total %
statement 100 108 92.5
branch 46 78 58.9
condition 20 42 47.6
subroutine 15 15 100.0
pod 8 8 100.0
total 189 251 75.3


line stmt bran cond sub pod time code
1             # This code is part of Perl distribution Mail-Message version 4.04.
2             # The POD got stripped from this file by OODoc version 3.06.
3             # For contributors see file ChangeLog.
4              
5             # This software is copyright (c) 2001-2026 by Mark Overmeer.
6              
7             # This is free software; you can redistribute it and/or modify it under
8             # the same terms as the Perl 5 programming language system itself.
9             # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later
10              
11              
12             package Mail::Message;{
13             our $VERSION = '4.04';
14             }
15              
16              
17 3     3   3654 use strict;
  3         8  
  3         151  
18 3     3   20 use warnings;
  3         7  
  3         270  
19              
20 3     3   21 use Log::Report 'mail-message', import => [ qw/__x error info trace/ ];
  3         7  
  3         34  
21              
22 3     3   1382 use Mail::Message::Body::Multipart ();
  3         11  
  3         85  
23 3     3   20 use Mail::Message::Body::Nested ();
  3         6  
  3         104  
24              
25 3     3   16 use Scalar::Util qw/blessed/;
  3         9  
  3         6406  
26              
27             #--------------------
28              
29             # tests in t/57forw1f.t
30              
31             sub forward(@)
32 3     3 1 1432 { my $self = shift;
33 3         19 my %args = @_;
34              
35             return $self->forwardNo(@_)
36 3 50       14 if exists $args{body};
37              
38 3   50     15 my $include = $args{include} || 'INLINE';
39 3 50       19 return $self->forwardInline(@_) if $include eq 'INLINE';
40              
41 0         0 my $preamble = $args{preamble};
42 0 0 0     0 push @_, preamble => Mail::Message::Body->new(data => $preamble)
43             if defined $preamble && ! ref $preamble;
44              
45 0 0       0 return $self->forwardAttach(@_) if $include eq 'ATTACH';
46 0 0       0 return $self->forwardEncapsulate(@_) if $include eq 'ENCAPSULATE';
47              
48 0         0 error __x"cannot include forward source as {kind UNKNOWN}.", kind => $include;
49 0         0 undef;
50             }
51              
52              
53             sub forwardNo(@)
54 7     7 1 47 { my ($self, %args) = @_;
55 7 50       30 my $body = $args{body} or error __x"method forwardNo requires a body.";
56 7 50       33 my $to = $args{To} or error __x"method forwardNo requires a To.";
57              
58             #
59             # Collect header info
60             #
61              
62 7         55 my $mainhead = $self->toplevel->head;
63              
64             # Where it comes from
65 7         16 my $from = $args{From};
66 7 50       19 unless(defined $from)
67 7         46 { my @from = $self->to;
68 7 50       1245 $from = \@from if @from;
69             }
70              
71             # Create a subject
72 7         22 my $srcsub = $args{Subject};
73 7 0       42 my $subject
    50          
74             = ! defined $srcsub ? $self->forwardSubject($self->subject)
75             : ref $srcsub ? $srcsub->($self->subject)
76             : $srcsub;
77              
78             # Create a nice message-id
79 7   33     54 my $msgid = $args{'Message-ID'} || $mainhead->createMessageId;
80 7 50 33     73 $msgid = "<$msgid>" if $msgid && $msgid !~ /^\s*\<.*\>\s*$/;
81              
82             # Thread information
83 7         38 my $origid = '<'.$self->messageId.'>';
84 7         21 my $refs = $mainhead->get('references');
85              
86 7 50 50     75 my $forward = Mail::Message->buildFromBody(
87             $body,
88             From => ($from || '(undisclosed)'),
89             To => $to,
90             Subject => $subject,
91             References => ($refs ? "$refs $origid" : $origid),
92             );
93              
94 7         28 my $newhead = $forward->head;
95 7 100       33 $newhead->set(Cc => $args{Cc} ) if $args{Cc};
96 7 100       44 $newhead->set(Bcc => $args{Bcc} ) if $args{Bcc};
97 7 50       24 $newhead->set(Date => $args{Date}) if $args{Date};
98              
99             # Ready
100              
101 7         38 $self->label(passed => 1);
102 7         57 trace "Forward created from $origid";
103 7         440 $forward;
104             }
105              
106              
107             sub forwardInline(@)
108 4     4 1 32 { my ($self, %args) = @_;
109              
110 4         19 my $body = $self->body;
111              
112 4         8 while(1) # simplify
113 4 50 33     68 { if($body->isMultipart && $body->parts==1) { $body = $body->part(0)->body }
  0 50       0  
114 0         0 elsif($body->isNested) { $body = $body->nested->body }
115 4         9 else { last }
116             }
117              
118             # Prelude must be a real body, otherwise concatenate will not work
119 4 100       20 my $prelude = exists $args{prelude} ? $args{prelude} : $self->forwardPrelude;
120              
121 4 100 66     39 $prelude = Mail::Message::Body->new(data => $prelude)
122             if defined $prelude && ! blessed $prelude;
123              
124             # Postlude
125 4 100       17 my $postlude = exists $args{postlude} ? $args{postlude} : $self->forwardPostlude;
126              
127             # Binary bodies cannot be inlined, therefore they will be rewritten
128             # into a forwardAttach... preamble must replace prelude and postlude.
129              
130 4 100 66     44 if($body->isMultipart || $body->isBinary)
131             { $args{preamble} ||= $prelude->concatenate(
132             $prelude,
133 1   50     57 ($args{is_attached} || "[The forwarded message is attached]\n"),
      33        
134             $postlude,
135             );
136 1         9 return $self->forwardAttach(%args);
137             }
138              
139 3         40 $body = $body->decoded;
140 3 100 66     26 if((!exists $args{strip_signature} || $args{strip_signature}) && !$body->isNested)
      66        
141 2         20 { $body = $body->stripSignature(pattern => $args{strip_signature}, max_lines => $args{max_signature});
142             }
143              
144 3 100       13 if(defined(my $quote = $args{quote}))
145 2 100   2   10 { my $quoting = ref $quote ? $quote : sub { $quote . $_ };
  2         5  
146 2         13 $body = $body->foreachLine($quoting);
147             }
148              
149             #
150             # Create the message.
151             #
152              
153 3         5 my $signature = $args{signature};
154 3 50 33     14 $signature = $signature->body
155             if defined $signature && $signature->isa('Mail::Message');
156              
157 3 50       25 my $composed = $body->concatenate(
158             $prelude, $body, $postlude,
159             (defined $signature ? "-- \n" : undef), $signature
160             );
161              
162 3         26 $self->forwardNo(%args, body => $composed);
163             }
164              
165              
166             sub forwardAttach(@)
167 3     3 1 1386 { my ($self, %args) = @_;
168              
169 3         20 my $body = $self->body;
170 3 100       16 if($body->isMultipart)
171             { $body = $body->stripSignature(pattern => $args{strip_signature}, max_lines => $args{max_signature})
172 1 50 33     15 if !exists $args{strip_signature} || $args{strip_signature};
173 1 50       6 $body = $body->part(0)->body if $body->parts == 1;
174             }
175              
176             my $preamble = $args{preamble}
177 3 50       15 or error __x"method forwardAttach requires a preamble.";
178              
179 3         10 my @parts = ($preamble, $body);
180 3 50       13 push @parts, $args{signature} if defined $args{signature};
181 3         33 my $multi = Mail::Message::Body::Multipart->new(parts => \@parts);
182              
183 3         24 $self->forwardNo(%args, body => $multi);
184             }
185              
186              
187             sub forwardEncapsulate(@)
188 1     1 1 5 { my ($self, %args) = @_;
189              
190             my $preamble = $args{preamble}
191 1 50       6 or error __x"method forwardEncapsulate requires a preamble.";
192              
193 1         6 my $nested = Mail::Message::Body::Nested->new(nested => $self->clone);
194 1         4 my @parts = ($preamble, $nested);
195 1 50       3 push @parts, $args{signature} if defined $args{signature};
196              
197 1         7 my $multi = Mail::Message::Body::Multipart->new(parts => \@parts);
198 1         9 $self->forwardNo(%args, body => $multi);
199             }
200              
201              
202             # tests in t/57forw0s.t
203              
204             sub forwardSubject($)
205 14     14 1 346039 { my ($self, $subject) = @_;
206 14 100 100     136 defined $subject && length $subject ? "Forw: $subject" : "Forwarded";
207             }
208              
209              
210             sub forwardPrelude()
211 1     1 1 4 { my $head = shift->head;
212              
213 1         3 my @lines = "---- BEGIN forwarded message\n";
214 1         6 my $from = $head->get('from');
215 1         3 my $to = $head->get('to');
216 1         2 my $cc = $head->get('cc');
217 1         2 my $date = $head->get('date');
218              
219 1 50       11 push @lines, $from->string if defined $from;
220 1 50       5 push @lines, $to->string if defined $to;
221 1 50       4 push @lines, $cc->string if defined $cc;
222 1 50       4 push @lines, $date->string if defined $date;
223 1         3 push @lines, "\n";
224              
225 1         3 \@lines;
226             }
227              
228              
229             sub forwardPostlude()
230 1     1 1 2 { my $self = shift;
231 1         3 [ "---- END forwarded message\n" ];
232             }
233              
234             #--------------------
235              
236             1;