File Coverage

blib/lib/Mail/Message/Construct/Build.pm
Criterion Covered Total %
statement 66 93 70.9
branch 28 80 35.0
condition 4 14 28.5
subroutine 12 12 100.0
pod 2 2 100.0
total 112 201 55.7


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 7     7   1267 use strict;
  7         18  
  7         337  
18 7     7   37 use warnings;
  7         14  
  7         478  
19              
20 7     7   37 use Log::Report 'mail-message', import => [ qw/__x error info warning/ ];
  7         16  
  7         60  
21              
22 7     7   1531 use Mail::Message::Head::Complete ();
  7         13  
  7         156  
23 7     7   66 use Mail::Message::Body::Lines ();
  7         14  
  7         151  
24 7     7   32 use Mail::Message::Body::Multipart ();
  7         15  
  7         166  
25 7     7   33 use Mail::Message::Body::Nested ();
  7         12  
  7         122  
26 7     7   29 use Mail::Message::Field ();
  7         14  
  7         166  
27              
28 7     7   35 use Mail::Address ();
  7         16  
  7         208  
29 7     7   33 use Scalar::Util qw/blessed/;
  7         11  
  7         8875  
30              
31             #--------------------
32              
33             sub build(@)
34 2     2 1 8 { my $class = shift;
35              
36 2 50       32 ! $class->isa('Mail::Box::Message')
37             or error __x"only build() Mail::Message's; they are not in a folder yet.";
38              
39             my @parts
40 2 0       13 = ! blessed $_[0] ? ()
    0          
    50          
41             : $_[0]->isa('Mail::Message') ? shift
42             : $_[0]->isa('Mail::Message::Body') ? shift
43             : ();
44              
45 2         11 my ($head, @headerlines);
46 2         0 my ($type, $transfenc, $dispose, $descr, $cid, $lang);
47 2         12 while(@_)
48 9         25 { my $key = shift;
49              
50 9 50 33     28 if(blessed $key && $key->isa('Mail::Message::Field'))
51 0         0 { my $name = $key->name;
52 0 0       0 if($name eq 'content-type') { $type = $key }
  0 0       0  
    0          
    0          
    0          
    0          
53 0         0 elsif($name eq 'content-transfer-encoding') { $transfenc = $key }
54 0         0 elsif($name eq 'content-disposition') { $dispose = $key }
55 0         0 elsif($name eq 'content-description') { $descr = $key }
56 0         0 elsif($name eq 'content-language') { $lang = $key }
57 0         0 elsif($name eq 'content-id') { $cid = $key }
58 0         0 else { push @headerlines, $key }
59 0         0 next;
60             }
61              
62 9   50     27 my $value = shift // next;
63              
64 9         16 my @data;
65              
66 9 50 33     74 if($key eq 'head')
    100          
    50          
    50          
    50          
    50          
67 0         0 { $head = $value }
68             elsif($key eq 'data')
69 3         29 { @data = Mail::Message::Body->new(data => $value) }
70             elsif($key eq 'file' || $key eq 'files')
71 0 0       0 { @data = map Mail::Message::Body->new(file => $_), ref $value eq 'ARRAY' ? @$value : $value;
72             }
73             elsif($key eq 'attach')
74 0 0       0 { foreach my $c (ref $value eq 'ARRAY' ? @$value : $value)
75 0 0       0 { defined $c or next;
76 0 0 0     0 push @data, blessed $c && $c->isa('Mail::Message') ? Mail::Message::Body::Nested->new(nested => $c) : $c;
77             }
78             }
79             elsif($key =~ m/^content\-(type|transfer\-encoding|disposition|language|description|id)$/i )
80 0         0 { my $k = lc $1;
81 0         0 my $field = Mail::Message::Field->new($key, $value);
82 0 0       0 if($k eq 'type') { $type = $field }
  0 0       0  
    0          
    0          
    0          
83 0         0 elsif($k eq 'disposition') { $dispose = $field }
84 0         0 elsif($k eq 'description') { $descr = $field }
85 0         0 elsif($k eq 'language') { $lang = $field }
86 0         0 elsif($k eq 'id') { $cid = $field }
87 0         0 else { $transfenc = $field }
88             }
89             elsif($key =~ m/^[A-Z]/)
90 6         19 { push @headerlines, $key, $value }
91             else
92 0         0 { warning __x"skipped unknown key '{key}' in build.", key => $key;
93             }
94              
95 9         34 push @parts, grep defined, @data;
96             }
97              
98 2 100       112 my $body
    50          
99             = @parts==0 ? Mail::Message::Body::Lines->new
100             : @parts==1 ? $parts[0]
101             : Mail::Message::Body::Multipart->new(parts => \@parts);
102              
103             # Setting the type explicitly, only after the body object is finalized
104 2 50       10 $body->type($type) if defined $type;
105 2 50       8 $body->disposition($dispose) if defined $dispose;
106 2 50       10 $body->description($descr) if defined $descr;
107 2 50       7 $body->language($lang) if defined $lang;
108 2 50       9 $body->contentId($cid) if defined $cid;
109 2 50       23 $body->transferEncoding($transfenc) if defined $transfenc;
110              
111 2         15 $class->buildFromBody($body, $head, @headerlines);
112             }
113              
114              
115             sub buildFromBody(@)
116 23     23 1 2461 { my ($class, $body) = (shift, shift);
117              
118 23         48 my $head;
119 23 50 33     117 if(blessed $_[0] && $_[0]->isa('Mail::Message::Head')) { $head = shift }
  0         0  
120             else
121 23 100       74 { defined $_[0] or shift; # explicit undef as head
122 23         149 $head = Mail::Message::Head::Complete->new;
123             }
124              
125 23         88 while(@_)
126 80 50       179 { if(blessed $_[0]) { $head->add(shift) }
  0         0  
127 80         318 else { $head->add(shift, shift) }
128             }
129              
130 23         115 my $message = $class->new(head => $head);
131 23         133 $message->body($body);
132              
133             # be sure the message-id is actually stored in the header.
134 23 100       125 defined $head->get('message-id') or $head->add('Message-Id' => '<'.$message->messageId.'>');
135 23 100       86 defined $head->get('Date') or $head->add(Date => Mail::Message::Field->toDate);
136 23 50       99 defined $head->get('MIME-Version') or $head->add('MIME-Version' => '1.0'); # required by rfc2045
137              
138 23         150 $message;
139             }
140              
141             #--------------------
142              
143             1;