File Coverage

blib/lib/Email/Stuffer.pm
Criterion Covered Total %
statement 173 185 93.5
branch 67 100 67.0
condition 13 21 61.9
subroutine 36 38 94.7
pod 19 20 95.0
total 308 364 84.6


line stmt bran cond sub pod time code
1 9     9   607526 use v5.12.0;
  9         136  
2 9     9   50 use warnings;
  9         23  
  9         435  
3             package Email::Stuffer 0.020;
4             # ABSTRACT: A more casual approach to creating and sending Email:: emails
5              
6 9     9   51 use Scalar::Util qw(blessed);
  9         26  
  9         754  
7              
8             #pod =head1 SYNOPSIS
9             #pod
10             #pod # Prepare the message
11             #pod my $body = <<'AMBUSH_READY';
12             #pod Dear Santa
13             #pod
14             #pod I have killed Bun Bun.
15             #pod
16             #pod Yes, I know what you are thinking... but it was actually a total accident.
17             #pod
18             #pod I was in a crowded line at a BayWatch signing, and I tripped, and stood on
19             #pod his head.
20             #pod
21             #pod I know. Oops! :/
22             #pod
23             #pod So anyways, I am willing to sell you the body for $1 million dollars.
24             #pod
25             #pod Be near the pinhole to the Dimension of Pain at midnight.
26             #pod
27             #pod Alias
28             #pod
29             #pod AMBUSH_READY
30             #pod
31             #pod # Create and send the email in one shot
32             #pod Email::Stuffer->from ('cpan@ali.as' )
33             #pod ->to ('santa@northpole.org' )
34             #pod ->bcc ('bunbun@sluggy.com' )
35             #pod ->text_body($body )
36             #pod ->attach_file('dead_bunbun_faked.gif' )
37             #pod ->send;
38             #pod
39             #pod =head1 DESCRIPTION
40             #pod
41             #pod B
42             #pod name and/or API changes>
43             #pod
44             #pod Email::Stuffer, as its name suggests, is a fairly casual module used
45             #pod to stuff things into an email and send them. It is a high-level module
46             #pod designed for ease of use when doing a very specific common task, but
47             #pod implemented on top of the light and tolerable Email:: modules.
48             #pod
49             #pod Email::Stuffer is typically used to build emails and send them in a single
50             #pod statement, as seen in the synopsis. And it is certain only for use when
51             #pod creating and sending emails. As such, it contains no email parsing
52             #pod capability, and little to no modification support.
53             #pod
54             #pod To re-iterate, this is very much a module for those "slap it together and
55             #pod fire it off" situations, but that still has enough grunt behind the scenes
56             #pod to do things properly.
57             #pod
58             #pod =head2 Default Transport
59             #pod
60             #pod Although it cannot be relied upon to work, the default behaviour is to
61             #pod use C to send mail, if you don't provide the mail send channel
62             #pod with either the C method, or as an argument to C.
63             #pod
64             #pod (Actually, the choice of default is delegated to
65             #pod L, which makes its own choices. But usually, it
66             #pod uses C.)
67             #pod
68             #pod =head2 Why use this?
69             #pod
70             #pod Why not just use L or L? After all, this just adds
71             #pod another layer of stuff around those. Wouldn't using them directly be better?
72             #pod
73             #pod Certainly, if you know EXACTLY what you are doing. The docs are clear enough,
74             #pod but you really do need to have an understanding of the structure of MIME
75             #pod emails. This structure is going to be different depending on whether you have
76             #pod text body, HTML, both, with or without an attachment etc.
77             #pod
78             #pod Then there's brevity... compare the following roughly equivalent code.
79             #pod
80             #pod First, the Email::Stuffer way.
81             #pod
82             #pod Email::Stuffer->to('Simon Cozens')
83             #pod ->from('Santa@northpole.org')
84             #pod ->text_body("You've been good this year. No coal for you.")
85             #pod ->attach_file('choochoo.gif')
86             #pod ->send;
87             #pod
88             #pod And now doing it directly with a knowledge of what your attachment is, and
89             #pod what the correct MIME structure is.
90             #pod
91             #pod use Email::MIME;
92             #pod use Email::Sender::Simple;
93             #pod use IO::All;
94             #pod
95             #pod Email::Sender::Simple->try_to_send(
96             #pod Email::MIME->create(
97             #pod header => [
98             #pod To => 'simon@somewhere.jp',
99             #pod From => 'santa@northpole.org',
100             #pod ],
101             #pod parts => [
102             #pod Email::MIME->create(
103             #pod body => "You've been a good boy this year. No coal for you."
104             #pod ),
105             #pod Email::MIME->create(
106             #pod body => io('choochoo.gif'),
107             #pod attributes => {
108             #pod filename => 'choochoo.gif',
109             #pod content_type => 'image/gif',
110             #pod },
111             #pod ),
112             #pod ],
113             #pod );
114             #pod );
115             #pod
116             #pod Again, if you know MIME well, and have the patience to manually code up
117             #pod the L structure, go do that, if you really want to.
118             #pod
119             #pod Email::Stuffer as the name suggests, solves one case and one case only:
120             #pod generate some stuff, and email it to somewhere, as conveniently as
121             #pod possible. DWIM, but do it as thinly as possible and use the solid
122             #pod Email:: modules underneath.
123             #pod
124             #pod =head1 COOKBOOK
125             #pod
126             #pod Here is another example (maybe plural later) of how you can use
127             #pod Email::Stuffer's brevity to your advantage.
128             #pod
129             #pod =head2 Custom Alerts
130             #pod
131             #pod package SMS::Alert;
132             #pod use base 'Email::Stuffer';
133             #pod
134             #pod sub new {
135             #pod shift()->SUPER::new(@_)
136             #pod ->from('monitor@my.website')
137             #pod # Of course, we could have pulled these from
138             #pod # $MyConfig->{support_tech} or something similar.
139             #pod ->to('0416181595@sms.gateway')
140             #pod ->transport('SMTP', { host => '123.123.123.123' });
141             #pod }
142             #pod
143             #pod Z<>
144             #pod
145             #pod package My::Code;
146             #pod
147             #pod unless ( $Server->restart ) {
148             #pod # Notify the admin on call that a server went down and failed
149             #pod # to restart.
150             #pod SMS::Alert->subject("Server $Server failed to restart cleanly")
151             #pod ->send;
152             #pod }
153             #pod
154             #pod =head1 METHODS
155             #pod
156             #pod As you can see from the synopsis, all methods that B the
157             #pod Email::Stuffer object returns the object, and thus most normal calls are
158             #pod chainable.
159             #pod
160             #pod However, please note that C, and the group of methods that do not
161             #pod change the Email::Stuffer object B return the object, and thus
162             #pod B chainable.
163             #pod
164             #pod =cut
165              
166 9     9   57 use Carp qw(croak);
  9         16  
  9         432  
167 9     9   56 use File::Basename ();
  9         34  
  9         335  
168 9     9   4326 use Params::Util 1.05 qw(_INSTANCE _INSTANCEDOES);
  9         57420  
  9         657  
169 9     9   5260 use Email::MIME 1.943 ();
  9         516154  
  9         263  
170 9     9   77 use Email::MIME::Creator ();
  9         19  
  9         133  
171 9     9   3951 use Email::Sender::Simple ();
  9         984626  
  9         262  
172 9     9   74 use Module::Runtime qw(require_module);
  9         21  
  9         40  
173              
174             #####################################################################
175             # Constructor and Accessors
176              
177             #pod =method new
178             #pod
179             #pod Creates a new, empty, Email::Stuffer object.
180             #pod
181             #pod You can pass a hashref of properties to set, including:
182             #pod
183             #pod =for :list
184             #pod * to
185             #pod * from
186             #pod * cc
187             #pod * bcc
188             #pod * reply_to
189             #pod * subject
190             #pod * text_body
191             #pod * html_body
192             #pod * transport
193             #pod
194             #pod The to, cc, bcc, and reply_to headers properties may be provided as array
195             #pod references. The array's contents will be used as the list of arguments to the
196             #pod setter.
197             #pod
198             #pod =cut
199              
200             my %IS_INIT_ARG = map {; $_ => 1 } qw(
201             to from cc bcc reply_to subject text_body html_body transport
202             );
203              
204             my %IS_ARRAY_ARG = map {; $_ => 1 } qw(
205             to cc bcc reply_to
206             transport
207             );
208              
209             sub new {
210 12 50   12 1 1029 Carp::croak("new method called on Email::Stuffer instance") if ref $_[0];
211              
212 12         40 my ($class, $arg) = @_;
213              
214 12         166 my $self = bless {
215             parts => [],
216             email => Email::MIME->create(
217             header => [],
218             parts => [],
219             ),
220             }, $class;
221              
222 12 100       34856 my @init_args = keys %{ $arg || {} };
  12         89  
223 12 50       75 if (my @bogus = grep {; ! $IS_INIT_ARG{$_} } @init_args) {
  2         9  
224 0         0 Carp::croak("illegal arguments to Email::Stuffer->new: @bogus");
225             }
226              
227 12         42 for my $init_arg (@init_args) {
228 2         6 my @args = $arg->{$init_arg};
229 2 50 66     15 if ($IS_ARRAY_ARG{$init_arg} && ref $args[0] && ref $args[0] eq 'ARRAY') {
      66        
230 1         3 @args = @{ $args[0] };
  1         3  
231             }
232              
233 2         9 $self->$init_arg(@args);
234             }
235              
236 12         42 $self;
237             }
238              
239             sub _self {
240 68     68   146 my $either = shift;
241 68 100       263 ref($either) ? $either : $either->new;
242             }
243              
244             #pod =method header_names
245             #pod
246             #pod Returns, as a list, all of the headers currently set for the Email
247             #pod For backwards compatibility, this method can also be called as B[headers].
248             #pod
249             #pod =cut
250              
251             sub header_names {
252 0     0 1 0 shift()->{email}->header_names;
253             }
254              
255             sub headers {
256 1     1 0 390 shift()->{email}->header_names; ## This is now header_names, headers is depreciated
257             }
258              
259             #pod =method parts
260             #pod
261             #pod Returns, as a list, the L parts for the Email
262             #pod
263             #pod =cut
264              
265             sub parts {
266 61     61 1 91 grep { defined $_ } @{shift()->{parts}};
  28         68  
  61         166  
267             }
268              
269             #####################################################################
270             # Header Methods
271              
272             #pod =method header
273             #pod
274             #pod $stuffer->header($header_name = $value)
275             #pod
276             #pod This method sets a named header in the email. Multiple calls with the same
277             #pod C<$header_name> will overwrite previous calls C<$value>.
278             #pod
279             #pod =cut
280              
281             sub header {
282 3     3 1 1450 my $self = shift()->_self;
283 3 50       11 return unless @_;
284 3         22 $self->{email}->header_str_set(ucfirst shift, shift);
285 3         2519 return $self;
286             }
287              
288             #pod =method to
289             #pod
290             #pod $stuffer->to(@addresses)
291             #pod
292             #pod This method sets the To header in the email.
293             #pod
294             #pod =cut
295              
296             sub _assert_addr_list_ok {
297 27     27   77 my ($self, $header, $allow_empty, $list) = @_;
298              
299 27 50 66     127 Carp::croak("$header is a required field")
300             unless $allow_empty or @$list;
301              
302 27         61 for (@$list) {
303 34 50       74 Carp::croak("list of $header headers contains undefined values")
304             unless defined;
305              
306 34 100 66     466 Carp::croak("list of $header headers contains unblessed references")
307             if ref && ! blessed $_;
308             }
309             }
310              
311             sub to {
312 12     12 1 1720 my $self = shift()->_self;
313 12         68 $self->_assert_addr_list_ok(to => 0 => \@_);
314 11 100       81 $self->{email}->header_str_set(To => (@_ > 1 ? \@_ : @_));
315 11         7586 return $self;
316             }
317              
318             #pod =method from
319             #pod
320             #pod $stuffer->from($address)
321             #pod
322             #pod
323             #pod This method sets the From header in the email.
324             #pod
325             #pod =cut
326              
327             sub from {
328 10     10 1 384980 my $self = shift()->_self;
329 10         56 $self->_assert_addr_list_ok(from => 0 => \@_);
330 10 50       37 Carp::croak("only one address is allowed in the from header") if @_ > 1;
331 10         71 $self->{email}->header_str_set(From => shift);
332 10         12301 return $self;
333             }
334              
335             #pod =method reply_to
336             #pod
337             #pod $stuffer->reply_to($address)
338             #pod
339             #pod This method sets the Reply-To header in the email.
340             #pod
341             #pod =cut
342              
343             sub reply_to {
344 1     1 1 573 my $self = shift()->_self;
345 1         5 $self->_assert_addr_list_ok('reply-to' => 0 => \@_);
346 1 50       4 Carp::croak("only one address is allowed in the reply-to header") if @_ > 1;
347 1         7 $self->{email}->header_str_set('Reply-To' => shift);
348 1         268 return $self;
349             }
350              
351             #pod =method cc
352             #pod
353             #pod $stuffer->cc(@addresses)
354             #pod
355             #pod This method sets the Cc header in the email.
356             #pod
357             #pod =cut
358              
359             sub cc {
360 2     2 1 1335 my $self = shift()->_self;
361 2         8 $self->_assert_addr_list_ok(cc => 1 => \@_);
362 1 50       8 $self->{email}->header_str_set(Cc => (@_ > 1 ? \@_ : @_));
363 1         395 return $self;
364             }
365              
366             #pod =method bcc
367             #pod
368             #pod $stuffer->bcc(@addresses)
369             #pod
370             #pod This method sets the Bcc header in the email.
371             #pod
372             #pod =cut
373              
374             sub bcc {
375 2     2 1 1227 my $self = shift()->_self;
376 2         9 $self->_assert_addr_list_ok(bcc => 1 => \@_);
377 1 50       9 $self->{email}->header_str_set(Bcc => (@_ > 1 ? \@_ : @_));
378 1         399 return $self;
379             }
380              
381             #pod =method subject
382             #pod
383             #pod $stuffer->subject($text)
384             #pod
385             #pod This method sets the Subject header in the email.
386             #pod
387             #pod =cut
388              
389             sub subject {
390 10     10 1 671 my $self = shift()->_self;
391 10 50       38 Carp::croak("subject is a required field") unless defined $_[0];
392 10         48 $self->{email}->header_str_set(Subject => shift);
393 10         854 return $self;
394             }
395              
396             #####################################################################
397             # Body and Attachments
398              
399             #pod =method text_body
400             #pod
401             #pod $stuffer->text_body($body, %attributes);
402             #pod
403             #pod Sets the text body of the email. Appropriate headers are set for you.
404             #pod You may override MIME attributes as needed. See the C
405             #pod parameter to L for the headers you can set.
406             #pod
407             #pod If C<$body> is undefined, this method will do nothing.
408             #pod
409             #pod Prior to Email::Stuffer version 0.015 text body was marked as flowed,
410             #pod which broke all pre-formated body text. Empty space at the beggining
411             #pod of the line was dropped and every new line character could be changed
412             #pod to one space (and vice versa). Version 0.015 (and later) does not set
413             #pod flowed format automatically anymore and so text body is really plain
414             #pod text. If you want to use old behavior of "advanced" flowed formatting,
415             #pod set flowed format manually by: C<< text_body($body, format => 'flowed') >>.
416             #pod
417             #pod =cut
418              
419             sub text_body {
420 7     7 1 24 my $self = shift()->_self;
421 7 50       29 my $body = defined $_[0] ? shift : return $self;
422 7         44 my %attr = (
423             # Defaults
424             content_type => 'text/plain',
425             charset => 'utf-8',
426             encoding => 'quoted-printable',
427             # Params overwrite them
428             @_,
429             );
430              
431             # Create the part in the text slot
432 7         41 $self->{parts}->[0] = Email::MIME->create(
433             attributes => \%attr,
434             body_str => $body,
435             );
436              
437 7         14049 $self;
438             }
439              
440             #pod =method html_body
441             #pod
442             #pod $stuffer->html_body($body, %attributes);
443             #pod
444             #pod Sets the HTML body of the email. Appropriate headers are set for you.
445             #pod You may override MIME attributes as needed. See the C
446             #pod parameter to L for the headers you can set.
447             #pod
448             #pod If C<$body> is undefined, this method will do nothing.
449             #pod
450             #pod =cut
451              
452             sub html_body {
453 2     2 1 9 my $self = shift()->_self;
454 2 50       12 my $body = defined $_[0] ? shift : return $self;
455 2         11 my %attr = (
456             # Defaults
457             content_type => 'text/html',
458             charset => 'utf-8',
459             encoding => 'quoted-printable',
460             # Params overwrite them
461             @_,
462             );
463              
464             # Create the part in the HTML slot
465 2         10 $self->{parts}->[1] = Email::MIME->create(
466             attributes => \%attr,
467             body_str => $body,
468             );
469              
470 2         3048 $self;
471             }
472              
473             #pod =method attach
474             #pod
475             #pod $stuffer->attach($contents, %attributes)
476             #pod
477             #pod Adds an attachment to the email. The first argument is the file contents
478             #pod followed by (as for text_body and html_body) the list of headers to use.
479             #pod Email::Stuffer will I to guess the headers correctly, but you may wish
480             #pod to provide them anyway to be sure. Encoding is Base64 by default. See
481             #pod the C parameter to L for the headers you
482             #pod can set.
483             #pod
484             #pod =cut
485              
486             sub _detect_content_type {
487 11     11   30 my ($filename, $body) = @_;
488              
489 11 100       28 if (defined($filename)) {
490 6 50       31 if ($filename =~ /\.([a-zA-Z]{3,4})\z/) {
491             my $content_type = {
492             'gif' => 'image/gif',
493             'png' => 'image/png',
494             'jpg' => 'image/jpeg',
495             'jpeg' => 'image/jpeg',
496             'txt' => 'text/plain',
497             'htm' => 'text/html',
498             'html' => 'text/html',
499             'css' => 'text/css',
500             'csv' => 'text/csv',
501             'pdf' => 'application/pdf',
502             'wav' => 'audio/wav',
503 6         65 }->{lc($1)};
504 6 50       36 return $content_type if defined $content_type;
505             }
506             }
507 5 50       25 if ($body =~ /
508             \A(?:
509             (GIF8) # gif
510             | (\xff\xd8) # jpeg
511             | (\x89PNG) # png
512             | (%PDF-) # pdf
513             )
514             /x) {
515 5 100       19 return 'image/gif' if $1;
516 4 100       14 return 'image/jpeg' if $2;
517 3 100       17 return 'image/png' if $3;
518 1 50       8 return 'application/pdf' if $4;
519             }
520 0         0 return 'application/octet-stream';
521             }
522              
523             sub attach {
524 12     12 1 512 my $self = shift()->_self;
525 12 50       37 my $body = defined $_[0] ? shift : return undef;
526 12         49 my %attr = (
527             # Cheap defaults
528             encoding => 'base64',
529             # Params overwrite them
530             @_,
531             );
532              
533             # The more expensive defaults if needed
534 12 100       46 unless ( $attr{content_type} ) {
535 11         38 $attr{content_type} = _detect_content_type($attr{filename}, $body);
536             }
537              
538             ### MORE?
539              
540             # Determine the slot to put it at
541 12         26 my $slot = scalar @{$self->{parts}};
  12         25  
542 12 100       30 $slot = 3 if $slot < 3;
543              
544             # Create the part in the attachment slot
545 12         77 $self->{parts}->[$slot] = Email::MIME->create(
546             attributes => \%attr,
547             body => $body,
548             );
549              
550 12         18719 $self;
551             }
552              
553             #pod =method attach_file
554             #pod
555             #pod $stuffer->attach_file($file, %attributes)
556             #pod
557             #pod Attachs a file that already exists on the filesystem to the email.
558             #pod C will attempt to auto-detect the MIME type, and use the
559             #pod file's current name when attaching. See the C parameter to
560             #pod L for the headers you can set.
561             #pod
562             #pod C<$file> can be a filename or an IO::All::File object.
563             #pod
564             #pod =cut
565              
566             sub attach_file {
567 9     9 1 5452 my $self = shift;
568 9         19 my $body_arg = shift;
569 9         17 my $name = undef;
570 9         12 my $body = undef;
571              
572             # Support IO::All::File arguments
573 9 50 66     106 if ( Params::Util::_INSTANCE($body_arg, 'IO::All::File') ) {
    100          
574 0         0 $body_arg->binmode;
575 0         0 $name = $body_arg->name;
576 0         0 $body = $body_arg->all;
577              
578             # Support file names
579             } elsif ( defined $body_arg and Params::Util::_STRING($body_arg) ) {
580 8 100       346 croak "No such file '$body_arg'" unless -f $body_arg;
581 7         23 $name = $body_arg;
582 7         23 $body = _slurp( $body_arg );
583              
584             # That's it
585             } else {
586 1   33     6 my $type = ref($body_arg) || "<$body_arg>";
587 1         85 croak "Expected a file name or an IO::All::File derivative, got $type";
588             }
589              
590             # Clean the file name
591 7         309 $name = File::Basename::basename($name);
592              
593 7 50       28 croak("basename somehow returned undef") unless defined $name;
594              
595             # Now attach as normal
596 7         32 $self->attach( $body, name => $name, filename => $name, @_ );
597             }
598              
599             # Provide a simple _slurp implementation
600             sub _slurp {
601 8     8   690 my $file = shift;
602 8         39 local $/ = undef;
603              
604 8 100       450 open my $slurp, '<:raw', $file or croak("error opening $file: $!");
605 7         354 my $source = <$slurp>;
606 7 50       120 close( $slurp ) or croak "error after slurping $file: $!";
607 7         60 \$source;
608             }
609              
610             #pod =method transport
611             #pod
612             #pod $stuffer->transport( $moniker, @options )
613             #pod
614             #pod or
615             #pod
616             #pod $stuffer->transport( $transport_obj )
617             #pod
618             #pod The C method specifies the L transport that
619             #pod you want to use to send the email, and any options that need to be
620             #pod used to instantiate the transport. C<$moniker> is used as the transport
621             #pod name; if it starts with an equals sign (C<=>) then the text after the
622             #pod sign is used as the class. Otherwise, the text is prepended by
623             #pod C.
624             #pod
625             #pod Alternatively, you can pass a complete transport object (which must be
626             #pod an L object) and it will be used as is.
627             #pod
628             #pod =cut
629              
630             sub transport {
631 7     7 1 29 my $self = shift()->_self;
632              
633 7 50       30 if ( @_ ) {
634             # Change the transport
635 7 50       44 if ( _INSTANCEDOES($_[0], 'Email::Sender::Transport') ) {
636 7         465 $self->{transport} = shift;
637             } else {
638 0         0 my ($moniker, @arg) = @_;
639 0 0       0 my $class = $moniker =~ s/\A=//
640             ? $moniker
641             : "Email::Sender::Transport::$moniker";
642 0         0 require_module($class);
643 0         0 my $transport = $class->new(@arg);
644 0         0 $self->{transport} = $transport;
645             }
646             }
647              
648 7         34 $self;
649             }
650              
651             #####################################################################
652             # Output Methods
653              
654             #pod =method email
655             #pod
656             #pod my $email_mime = $stuffer->email;
657             #pod
658             #pod This method creates and returns the full L object for the email.
659             #pod
660             #pod =cut
661              
662             sub email {
663 61     61 1 11807 my $self = shift;
664 61         140 my @parts = $self->parts;
665              
666             ### Lyle Hopkins, code added to Fix single part, and multipart/alternative
667             ### problems
668 61 100       89 if (scalar(@{ $self->{parts} }) >= 3) {
  61 100       164  
669             ## multipart/mixed
670 3         22 $self->{email}->parts_set(\@parts);
671 58         144 } elsif (scalar(@{ $self->{parts} })) {
672             ## Check we actually have any parts
673 5 100 66     122 if ( _INSTANCE($parts[0], 'Email::MIME')
    50          
674             && _INSTANCE($parts[1], 'Email::MIME')
675             ) {
676             ## multipart/alternate
677 1         10 $self->{email}->header_set('Content-Type' => 'multipart/alternative');
678 1         69 $self->{email}->parts_set(\@parts);
679             } elsif (_INSTANCE($parts[0], 'Email::MIME')) {
680             ## As @parts is $self->parts without the blanks, we only need check
681             ## $parts[0]
682             ## single part text/plain
683 4         20 _transfer_headers($self->{email}, $parts[0]);
684 4         322 $self->{email} = $parts[0];
685             }
686             }
687              
688 61         25506 $self->{email};
689             }
690              
691             # Support coercion to an Email::MIME
692 0     0   0 sub __as_Email_MIME { shift()->email }
693              
694             # Quick any routine
695             sub _any (&@) {
696 20     20   35 my $f = shift;
697 20 50       40 return if ! @_;
698 20         30 for (@_) {
699 60 100       79 return 1 if $f->();
700             }
701 12         24 return 0;
702             }
703              
704             # header transfer from one object to another
705             sub _transfer_headers {
706             # $_[0] = from, $_[1] = to
707 4     4   22 my @headers_move = $_[0]->header_names;
708 4         170 my @headers_skip = $_[1]->header_names;
709 4         106 foreach my $header_name (@headers_move) {
710 20 100   60   1915 next if _any { $_ eq $header_name } @headers_skip;
  60         143  
711 12         43 my @values = $_[0]->header($header_name);
712 12         510 $_[1]->header_str_set( $header_name, @values );
713             }
714             }
715              
716             #pod =method as_string
717             #pod
718             #pod my $email_document = $stuffer->as_string;
719             #pod
720             #pod Returns the string form of the email. Identical to (and uses behind the
721             #pod scenes) C<< Email::MIME->as_string >>.
722             #pod
723             #pod =cut
724              
725             sub as_string {
726 31     31 1 3548 shift()->email->as_string;
727             }
728              
729             #pod =method send
730             #pod
731             #pod $stuffer->send;
732             #pod
733             #pod or
734             #pod
735             #pod $stuffer->send({ to => [ $to_1, $to_2 ], from => $sender });
736             #pod
737             #pod Sends the email via L.
738             #pod L
739             #pod can be specified in a hash reference.
740             #pod
741             #pod On failure, returns false.
742             #pod
743             #pod =cut
744              
745             sub send {
746 5     5 1 11 my $self = shift;
747 5         10 my $arg = shift;
748 5 50       16 my $email = $self->email or return undef;
749              
750 5         13 my $transport = $self->{transport};
751              
752 5 50       56 Email::Sender::Simple->try_to_send(
    50          
753             $email,
754             {
755             ($transport ? (transport => $transport) : ()),
756             $arg ? %$arg : (),
757             },
758             );
759             }
760              
761             #pod =method send_or_die
762             #pod
763             #pod $stuffer->send_or_die;
764             #pod
765             #pod or
766             #pod
767             #pod $stuffer->send_or_die({ to => [ $to_1, $to_2 ], from => $sender });
768             #pod
769             #pod Sends the email via L.
770             #pod L
771             #pod can be specified in a hash reference.
772             #pod
773             #pod On failure, throws an exception.
774             #pod
775             #pod =cut
776              
777             sub send_or_die {
778 2     2 1 4 my $self = shift;
779 2         4 my $arg = shift;
780 2 50       7 my $email = $self->email or return undef;
781              
782 2         5 my $transport = $self->{transport};
783              
784 2 50       22 Email::Sender::Simple->send(
    50          
785             $email,
786             {
787             ($transport ? (transport => $transport) : ()),
788             $arg ? %$arg : (),
789             },
790             );
791             }
792              
793             1;
794              
795             #pod =head1 TO DO
796             #pod
797             #pod =for :list
798             #pod * Fix a number of bugs still likely to exist
799             #pod * Write more tests.
800             #pod * Add any additional small bit of automation that isn't too expensive
801             #pod
802             #pod =head1 SEE ALSO
803             #pod
804             #pod L, L, L
805             #pod
806             #pod =cut
807              
808             __END__