File Coverage

blib/lib/Mail/Message/Construct/Build.pm
Criterion Covered Total %
statement 64 91 70.3
branch 28 76 36.8
condition 3 12 25.0
subroutine 11 11 100.0
pod 2 2 100.0
total 108 192 56.2


line stmt bran cond sub pod time code
1             # Copyrights 2001-2023 by [Mark Overmeer ].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.03.
5             # This code is part of distribution Mail-Message. Meta-POD processed with
6             # OODoc into POD and HTML manual-pages. See README.md
7             # Copyright Mark Overmeer. Licensed under the same terms as Perl itself.
8              
9             package Mail::Message;
10 7     7   945 use vars '$VERSION';
  7         20  
  7         463  
11             $VERSION = '3.013';
12              
13              
14 7     7   54 use strict;
  7         16  
  7         154  
15 7     7   35 use warnings;
  7         16  
  7         231  
16              
17 7     7   42 use Mail::Message::Head::Complete ();
  7         16  
  7         99  
18 7     7   34 use Mail::Message::Body::Lines ();
  7         16  
  7         113  
19 7     7   36 use Mail::Message::Body::Multipart ();
  7         14  
  7         103  
20 7     7   34 use Mail::Message::Body::Nested ();
  7         11  
  7         102  
21 7     7   37 use Mail::Message::Field ();
  7         35  
  7         110  
22              
23 7     7   32 use Mail::Address ();
  7         15  
  7         5702  
24              
25              
26             sub build(@)
27 2     2 1 7 { my $class = shift;
28              
29 2 50       20 if($class->isa('Mail::Box::Message'))
30 0         0 { $class->log(ERROR
31             => "Only build() Mail::Message's; they are not in a folder yet");
32 0         0 return undef;
33             }
34              
35             my @parts
36 2 0       8 = ! ref $_[0] ? ()
    0          
    50          
37             : $_[0]->isa('Mail::Message') ? shift
38             : $_[0]->isa('Mail::Message::Body') ? shift
39             : ();
40              
41 2         8 my ($head, @headerlines);
42 2         0 my ($type, $transfenc, $dispose, $descr, $cid);
43 2         7 while(@_)
44 9         17 { my $key = shift;
45 9 50 33     23 if(ref $key && $key->isa('Mail::Message::Field'))
46 0         0 { my $name = $key->name;
47 0 0       0 if($name eq 'content-type') { $type = $key }
  0 0       0  
    0          
    0          
    0          
48 0         0 elsif($name eq 'content-transfer-encoding') { $transfenc = $key }
49 0         0 elsif($name eq 'content-disposition') { $dispose = $key }
50 0         0 elsif($name eq 'content-description') { $descr = $key }
51 0         0 elsif($name eq 'content-id') { $cid = $key }
52 0         0 else { push @headerlines, $key }
53 0         0 next;
54             }
55              
56 9         19 my $value = shift;
57 9 50       17 next unless defined $value;
58              
59 9         15 my @data;
60              
61 9 50 33     54 if($key eq 'head')
    100          
    50          
    50          
    50          
    50          
62 0         0 { $head = $value }
63             elsif($key eq 'data')
64 3         15 { @data = Mail::Message::Body->new(data => $value) }
65             elsif($key eq 'file' || $key eq 'files')
66 0 0       0 { @data = map Mail::Message::Body->new(file => $_)
67             , ref $value eq 'ARRAY' ? @$value : $value;
68             }
69             elsif($key eq 'attach')
70 0 0       0 { foreach my $c (ref $value eq 'ARRAY' ? @$value : $value)
71 0 0       0 { defined $c or next;
72 0 0 0     0 push @data, ref $c && $c->isa('Mail::Message')
73             ? Mail::Message::Body::Nested->new(nested => $c)
74             : $c;
75             }
76             }
77             elsif($key =~
78             m/^content\-(type|transfer\-encoding|disposition|description|id)$/i )
79 0         0 { my $k = lc $1;
80 0         0 my $field = Mail::Message::Field->new($key, $value);
81 0 0       0 if($k eq 'type') { $type = $field }
  0 0       0  
    0          
    0          
82 0         0 elsif($k eq 'disposition') { $dispose = $field }
83 0         0 elsif($k eq 'description') { $descr = $field }
84 0         0 elsif($k eq 'id') { $cid = $field }
85 0         0 else { $transfenc = $field }
86             }
87             elsif($key =~ m/^[A-Z]/)
88 6         15 { push @headerlines, $key, $value }
89             else
90 0         0 { $class->log(WARNING => "Skipped unknown key '$key' in build");
91             }
92              
93 9         40 push @parts, grep defined, @data;
94             }
95              
96 2 100       25 my $body
    50          
97             = @parts==0 ? Mail::Message::Body::Lines->new()
98             : @parts==1 ? $parts[0]
99             : Mail::Message::Body::Multipart->new(parts => \@parts);
100              
101             # Setting the type explicitly, only after the body object is finalized
102 2 50       8 $body->type($type) if defined $type;
103 2 50       7 $body->disposition($dispose) if defined $dispose;
104 2 50       6 $body->description($descr) if defined $descr;
105 2 50       17 $body->contentId($cid) if defined $cid;
106 2 50       6 $body->transferEncoding($transfenc) if defined $transfenc;
107              
108 2         9 $class->buildFromBody($body, $head, @headerlines);
109             }
110              
111             #------------------------------------------
112              
113              
114             sub buildFromBody(@)
115 23     23 1 1692 { my ($class, $body) = (shift, shift);
116 23         126 my @log = $body->logSettings;
117              
118 23         143 my $head;
119 23 50 33     100 if(ref $_[0] && $_[0]->isa('Mail::Message::Head')) { $head = shift }
  0         0  
120             else
121 23 100       62 { shift unless defined $_[0]; # undef as head
122 23         116 $head = Mail::Message::Head::Complete->new(@log);
123             }
124              
125 23         140 while(@_)
126 80 50       169 { if(ref $_[0]) {$head->add(shift)}
  0         0  
127 80         206 else {$head->add(shift, shift)}
128             }
129              
130 23         97 my $message = $class->new
131             ( head => $head
132             , @log
133             );
134              
135 23         110 $message->body($body);
136              
137             # be sure the message-id is actually stored in the header.
138 23 100       85 $head->add('Message-Id' => '<'.$message->messageId.'>')
139             unless defined $head->get('message-id');
140              
141 23 100       68 $head->add(Date => Mail::Message::Field->toDate)
142             unless defined $head->get('Date');
143              
144 23 50       75 $head->add('MIME-Version' => '1.0') # required by rfc2045
145             unless defined $head->get('MIME-Version');
146              
147 23         110 $message;
148             }
149              
150             #------------------------------------------
151              
152              
153             1;