File Coverage

blib/lib/Email/Stuff.pm
Criterion Covered Total %
statement 132 152 86.8
branch 36 62 58.0
condition 4 9 44.4
subroutine 33 44 75.0
pod 18 25 72.0
total 223 292 76.3


line stmt bran cond sub pod time code
1             package Email::Stuff;
2              
3             =head1 NAME
4              
5             Email::Stuff - A more casual approach to creating and sending Email:: emails
6              
7             =head1 ACHTUNG!
8              
9             B.>
10              
11             Email::Stuffer should be a drop-in replacement for almost all users. It uses
12             L in place of L. This won't usually cause a
13             noticeable change, but will be a lot easier to test.
14              
15             You will need to be careful if:
16              
17             =over
18              
19             =item *
20              
21             you use the C or C methods, which are replaced by C
22             in Stuffer
23              
24             =item *
25              
26             you inspect the false Return::Value object provided by Stuff in case of failure
27              
28             =item *
29              
30             you pass extra arguments to the C method
31              
32             =back
33              
34             =head1 SYNOPSIS
35              
36             # Prepare the message
37             my $body = <<'AMBUSH_READY';
38             Dear Santa
39            
40             I have killed Bun Bun.
41             Yes, I know what you are thinking... but it was actually a total accident. I
42             was in a crowded line at a BayWatch signing, and I tripped, and stood on his
43             head.
44             I know. Oops! :/
45              
46             So anyways, I am willing to sell you the body for $1 million dollars. Be
47             near the pinhole to the Dimension of Pain at midnight.
48              
49             Alias
50              
51             AMBUSH_READY
52              
53             # Create and send the email in one shot, and send via sendmail
54             Email::Stuff->from ('cpan@ali.as' )
55             ->to ('santa@northpole.org' )
56             ->bcc ('bunbun@sluggy.com' )
57             ->text_body($body )
58             ->attach (io('dead_bunbun_faked.gif')->all,
59             filename => 'dead_bunbun_proof.gif')
60             ->send;
61              
62             # Construct email before sending and send with SMTP.
63              
64             my $mail = Email::Stuff->from('cpan@ali.as');
65             $mail->to('santa@northpole.org')
66             # and so on ...
67             my $mailer = Email::Send->new({mailer => 'SMTP'});
68             $mailer->mailer_args([Host => 'smtp.example.com:465', ssl => 1]);
69             $mail->send($mailer);
70              
71             =head1 DESCRIPTION
72              
73             B
74             name and/or API changes>
75              
76             Email::Stuff, as its name suggests, is a fairly casual module used
77             to email "stuff" to people using the most common methods. It is a
78             high-level module designed for ease of use when doing a very specific
79             common task, but implemented on top of the tight and correct Email::
80             modules.
81              
82             Email::Stuff is typically used to build emails and send them in a single
83             statement, as seen in the synopsis. And it is certain only for use when
84             creating and sending emails. As such, it contains no email parsing
85             capability, and little to no modification support.
86              
87             To re-iterate, this is very much a module for those "slap it together and
88             fire it off" situations, but that still has enough grunt behind the scenes
89             to do things properly.
90              
91             =head2 Default Mailer
92              
93             Email::Stuff uses L to send messages. Although it cannot be
94             relied upon to work, the default behaviour is to use sendmail to send mail, if
95             you don't provide the mail send channel with either the C method, or as
96             an argument to C.
97              
98             The use of sendmail as the default mailer is consistent with the behaviour
99             of the L module itself.
100              
101             =head2 Why use this?
102              
103             Why not just use L or L? After all, this just adds
104             another layer of stuff around those. Wouldn't using them directly be better?
105              
106             Certainly, if you know EXACTLY what you are doing. The docs are clear enough,
107             but you really do need to have an understanding of the structure of MIME
108             emails. This structure is going to be different depending on whether you have
109             text body, HTML, both, with or without an attachment etc.
110              
111             Then there's brevity... compare the following roughly equivalent code.
112              
113             First, the Email::Stuff way.
114              
115             Email::Stuff->to('Simon Cozens')
116             ->from('Santa@northpole.org')
117             ->text_body("You've been a good boy this year. No coal for you.")
118             ->attach_file('choochoo.gif')
119             ->send;
120              
121             And now doing it directly with a knowledge of what your attachment is, and
122             what the correct MIME structure is.
123              
124             use Email::MIME;
125             use Email::Send;
126             use IO::All;
127            
128             send SMTP => Email::MIME->create(
129             header => [
130             To => 'simon@somewhere.jp',
131             From => 'santa@northpole.org',
132             ],
133             parts => [
134             Email::MIME->create(
135             body => "You've been a good boy this year. No coal for you."
136             ),
137             Email::MIME->create(
138             body => io('choochoo.gif'),
139             attributes => {
140             filename => 'choochoo.gif',
141             content_type => 'image/gif',
142             },
143             ),
144             ],
145             );
146              
147             Again, if you know MIME well, and have the patience to manually code up
148             the L structure, go do that.
149              
150             Email::Stuff, as the name suggests, solves one case and one case only.
151              
152             Generate some stuff, and email it to somewhere. As conveniently as
153             possible. DWIM, but do it as thinly as possible and use the solid
154             Email:: modules underneath.
155              
156             =head1 COOKBOOK
157              
158             Here is another example (maybe plural later) of how you can use
159             Email::Stuff's brevity to your advantage.
160              
161             =head2 Custom Alerts
162              
163             package SMS::Alert;
164             use base 'Email::Stuff';
165            
166             sub new {
167             shift()->SUPER::new(@_)
168             ->from('monitor@my.website')
169             # Of course, we could have pulled these from
170             # $MyConfig->{support_tech} or something similar.
171             ->to('0416181595@sms.gateway')
172             ->using('SMTP', Host => '123.123.123.123');
173             }
174              
175             package My::Code;
176            
177             unless ( $Server->restart ) {
178             # Notify the admin on call that a server went down and failed
179             # to restart.
180             SMS::Alert->subject("Server $Server failed to restart cleanly")
181             ->send;
182             }
183              
184             =head1 METHODS
185              
186             As you can see from the synopsis, all methods that B the
187             Email::Stuff object returns the object, and thus most normal calls are
188             chainable.
189              
190             However, please note that C, and the group of methods that do not
191             change the Email::Stuff object B return the object, and thus
192             B chainable.
193              
194             =cut
195              
196 4     4   100656 use 5.005;
  4         16  
  4         258  
197 4     4   25 use strict;
  4         7  
  4         142  
198 4     4   20 use Carp ();
  4         17  
  4         54  
199 4     4   20 use File::Basename ();
  4         13  
  4         72  
200 4     4   4197 use Params::Util '_INSTANCE';
  4         26311  
  4         385  
201 4     4   7428 use Email::MIME ();
  4         362419  
  4         92  
202 4     4   37 use Email::MIME::Creator ();
  4         10  
  4         63  
203 4     4   4564 use Email::Send ();
  4         74328  
  4         178  
204 4     4   4865 use prefork 'File::Type';
  4         4396  
  4         25  
205              
206 4     4   263 use vars qw{$VERSION};
  4         8  
  4         188  
207             BEGIN {
208 4     4   7312 $VERSION = '2.105';
209             }
210              
211             #####################################################################
212             # Constructor and Accessors
213              
214             =head2 new
215              
216             Creates a new, empty, Email::Stuff object.
217              
218             =cut
219              
220             sub new {
221 6   33 6 1 496 my $class = ref $_[0] || $_[0];
222              
223 6         72 my $self = bless {
224             send_using => [ 'Sendmail' ],
225             # mailer => undef,
226             parts => [],
227             email => Email::MIME->create(
228             header => [],
229             parts => [],
230             ),
231             }, $class;
232              
233 6         16885 $self;
234             }
235              
236             sub _self {
237 25     25   41 my $either = shift;
238 25 100       91 ref($either) ? $either : $either->new;
239             }
240              
241             =head2 header_names
242              
243             Returns, as a list, all of the headers currently set for the Email
244             For backwards compatibility, this method can also be called as B[headers].
245              
246             =cut
247              
248             sub header_names {
249 0     0 1 0 shift()->{email}->header_names;
250             }
251              
252             sub headers {
253 1     1 0 359 shift()->{email}->header_names; ## This is now header_names, headers is depreciated
254             }
255              
256             =head2 parts
257              
258             Returns, as a list, the L parts for the Email
259              
260             =cut
261              
262             sub parts {
263 21     21 1 28 grep { defined $_ } @{shift()->{parts}};
  13         30  
  21         56  
264             }
265              
266              
267              
268              
269              
270             #####################################################################
271             # Header Methods
272              
273             =head2 header $header => $value
274              
275             Adds a single named header to the email. Note I said B not set,
276             so you can just keep shoving the headers on. But of course, if you
277             want to use to overwrite a header, you're stuffed. Because B
278             is not for changing emails, just throwing stuff together and sending it.>
279              
280             =cut
281              
282             sub header {
283 0     0 1 0 my $self = shift()->_self;
284 0 0       0 $self->{email}->header_str_set(ucfirst shift, shift) ? $self : undef;
285             }
286              
287             =head2 to $address
288              
289             Adds a To: header to the email
290              
291             =cut
292              
293             sub to {
294 6     6 1 660 my $self = shift()->_self;
295 6 50       28 $self->{email}->header_str_set(To => shift) ? $self : undef;
296             }
297              
298             =head2 from $address
299              
300             Adds (yes ADDS, you only do it once) a From: header to the email
301              
302             =cut
303              
304             sub from {
305 6     6 1 7409 my $self = shift()->_self;
306 6 50       43 $self->{email}->header_str_set(From => shift) ? $self : undef;
307             }
308              
309             =head2 cc $address
310              
311             Adds a Cc: header to the email
312              
313             =cut
314              
315             sub cc {
316 0     0 1 0 my $self = shift()->_self;
317 0 0       0 $self->{email}->header_str_set(Cc => shift) ? $self : undef;
318             }
319              
320             =head2 bcc $address
321              
322             Adds a Bcc: header to the email
323              
324             =cut
325              
326             sub bcc {
327 0     0 1 0 my $self = shift()->_self;
328 0 0       0 $self->{email}->header_str_set(Bcc => shift) ? $self : undef;
329             }
330              
331             =head2 subject $text
332              
333             Adds a subject to the email
334              
335             =cut
336              
337             sub subject {
338 5     5 1 290 my $self = shift()->_self;
339 5 50       20 $self->{email}->header_str_set(Subject => shift) ? $self : undef;
340             }
341              
342             #####################################################################
343             # Body and Attachments
344              
345             =head2 text_body $body [, $header => $value, ... ]
346              
347             Sets the text body of the email. Unless specified, all the appropriate
348             headers are set for you. You may override any as needed. See
349             L for the actual headers to use.
350              
351             If C<$body> is undefined, this method will do nothing.
352              
353             =cut
354              
355             sub text_body {
356 4     4 1 206 my $self = shift()->_self;
357 4 50       15 my $body = defined $_[0] ? shift : return $self;
358 4         37 my %attr = (
359             # Defaults
360             content_type => 'text/plain',
361             charset => 'utf-8',
362             encoding => 'quoted-printable',
363             format => 'flowed',
364             # Params overwrite them
365             @_,
366             );
367              
368             # Create the part in the text slot
369 4         43 $self->{parts}->[0] = Email::MIME->create(
370             attributes => \%attr,
371             body_str => $body,
372             );
373              
374 4         4850 $self;
375             }
376              
377             =head2 html_body $body [, $header => $value, ... ]
378              
379             Set the HTML body of the email. Unless specified, all the appropriate
380             headers are set for you. You may override any as needed. See
381             L for the actual headers to use.
382              
383             If C<$body> is undefined, this method will do nothing.
384              
385             =cut
386              
387             sub html_body {
388 2     2 1 64 my $self = shift()->_self;
389 2 50       9 my $body = defined $_[0] ? shift : return $self;
390 2         13 my %attr = (
391             # Defaults
392             content_type => 'text/html',
393             charset => 'utf-8',
394             encoding => 'quoted-printable',
395             # Params overwrite them
396             @_,
397             );
398              
399             # Create the part in the HTML slot
400 2         11 $self->{parts}->[1] = Email::MIME->create(
401             attributes => \%attr,
402             body_str => $body,
403             );
404              
405 2         1757 $self;
406             }
407              
408             =head2 attach $contents [, $header => $value, ... ]
409              
410             Adds an attachment to the email. The first argument is the file contents
411             followed by (as for text_body and html_body) the list of headers to use.
412             Email::Stuff should TRY to guess the headers right, but you may wish
413             to provide them anyway to be sure. Encoding is Base64 by default.
414              
415             =cut
416              
417             sub attach {
418 2     2 1 6 my $self = shift()->_self;
419 2 50       5 my $body = defined $_[0] ? shift : return undef;
420 2         11 my %attr = (
421             # Cheap defaults
422             encoding => 'base64',
423             # Params overwrite them
424             @_,
425             );
426              
427             # The more expensive defaults if needed
428 2 100       7 unless ( $attr{content_type} ) {
429 1         2164 require File::Type;
430 1         24123 $attr{content_type} = File::Type->checktype_contents($body);
431             }
432              
433             ### MORE?
434              
435             # Determine the slot to put it at
436 2         451 my $slot = scalar @{$self->{parts}};
  2         8  
437 2 50       9 $slot = 3 if $slot < 3;
438              
439             # Create the part in the attachment slot
440 2         22 $self->{parts}->[$slot] = Email::MIME->create(
441             attributes => \%attr,
442             body => $body,
443             );
444              
445 2         2287 $self;
446             }
447              
448             =head2 attach_file $file [, $header => $value, ... ]
449              
450             Attachs a file that already exists on the filesystem to the email.
451             C will auto-detect the MIME type, and use the file's
452             current name when attaching.
453              
454             =cut
455              
456             sub attach_file {
457 2     2 1 23 my $self = shift;
458 2         4 my $body_arg = shift;
459 2         2 my $name = undef;
460 2         4 my $body = undef;
461              
462             # Support IO::All::File arguments
463 2 50 33     65 if ( Params::Util::_INSTANCE($body_arg, 'IO::All::File') ) {
    50          
464 0         0 $name = $body_arg->name;
465 0         0 $body = $body_arg->all;
466              
467             # Support file names
468             } elsif ( defined $body_arg and -f $body_arg ) {
469 2         2 $name = $body_arg;
470 2 50       8 $body = _slurp( $body_arg ) or return undef;
471              
472             # That's it
473             } else {
474 0         0 return undef;
475             }
476              
477             # Clean the file name
478 2 50       110 $name = File::Basename::basename($name) or return undef;
479              
480             # Now attach as normal
481 2         11 $self->attach( $body, name => $name, filename => $name, @_ );
482             }
483              
484             # Provide a simple _slurp implementation
485             sub _slurp {
486 2     2   3 my $file = shift;
487 2         11 local $/ = undef;
488 2         5 local *SLURP;
489 2 50       82 open( SLURP, "<$file" ) or return undef;
490 2         1579 my $source = ;
491 2 50       30 close( SLURP ) or return undef;
492 2         20 \$source;
493             }
494              
495             =head2 using $drivername, @options
496              
497             The C method specifies the L driver that you want to use to
498             send the email, and any options that need to be passed to the driver at the
499             time that we send the mail.
500              
501             Alternatively, you can pass a complete mailer object (which must be an
502             L object) and it will be used as is.
503              
504             =cut
505              
506             sub using {
507 5     5 1 12 my $self = shift;
508              
509 5 50       31 if ( @_ ) {
510             # Change the mailer
511 5 50       29 if ( _INSTANCE($_[0], 'Email::Send') ) {
512 0         0 $self->{mailer} = shift;
513 0         0 delete $self->{send_using};
514             } else {
515 5         18 $self->{send_using} = [ @_ ];
516 5         16 delete $self->{mailer};
517 5         20 $self->mailer;
518             }
519             }
520              
521 5         24 $self;
522             }
523              
524              
525              
526              
527              
528             #####################################################################
529             # Output Methods
530              
531             =head2 email
532              
533             Creates and returns the full L object for the email.
534              
535             =cut
536              
537             sub email {
538 21     21 1 3433 my $self = shift;
539 21         52 my @parts = $self->parts;
540              
541             ### Lyle Hopkins, code added to Fix single part, and multipart/alternative problems
542 21 100       24 if ( scalar( @{ $self->{parts} } ) >= 3 ) {
  21 100       65  
  19         49  
543             ## multipart/mixed
544 2         13 $self->{email}->parts_set( \@parts );
545             }
546             ## Check we actually have any parts
547             elsif ( scalar( @{ $self->{parts} } ) ) {
548 3 100 66     61 if ( _INSTANCE($parts[0], 'Email::MIME') && _INSTANCE($parts[1], 'Email::MIME') ) {
    50          
549             ## multipart/alternate
550 1         5 $self->{email}->header_set( 'Content-Type' => 'multipart/alternative' );
551 1         36 $self->{email}->parts_set( \@parts );
552             }
553             ## As @parts is $self->parts without the blanks, we only need check $parts[0]
554             elsif ( _INSTANCE($parts[0], 'Email::MIME') ) {
555             ## single part text/plain
556 2         8 _transfer_headers( $self->{email}, $parts[0] );
557 2         88 $self->{email} = $parts[0];
558             }
559             }
560              
561 21         26804 $self->{email};
562             }
563              
564             # Support coercion to an Email::MIME
565 0     0   0 sub __as_Email_MIME { shift()->email }
566              
567             # Quick any routine
568             sub _any (&@) {
569 10     10   11 my $f = shift;
570 10 50       18 return if ! @_;
571 10         11 for (@_) {
572 30 100       36 return 1 if $f->();
573             }
574 6         13 return 0;
575             }
576              
577             # header transfer from one object to another
578             sub _transfer_headers {
579             # $_[0] = from, $_[1] = to
580 2     2   11 my @headers_move = $_[0]->header_names;
581 2         62 my @headers_skip = $_[1]->header_names;
582 2         41 foreach my $header_name (@headers_move) {
583 10 100   30   202 next if _any { $_ eq $header_name } @headers_skip;
  30         77  
584 6         21 my @values = $_[0]->header($header_name);
585 6         179 $_[1]->header_str_set( $header_name, @values );
586             }
587             }
588              
589             =head2 as_string
590              
591             Returns the string form of the email. Identical to (and uses behind the
592             scenes) Email::MIME-Eas_string.
593              
594             =cut
595              
596             sub as_string {
597 9     9 1 770 shift()->email->as_string;
598             }
599              
600             =head2 send
601              
602             Sends the email via L. Optionally pass in a Mail:Send object to
603             override the default mailer.
604              
605             =cut
606              
607             sub send {
608 5     5 1 8 my $self = shift;
609 5 50       15 $self->using(@_) if @_; # Arguments are passed to ->using
610 5 50       17 my $email = $self->email or return undef;
611 5         20 $self->mailer->send( $email );
612             }
613              
614             sub _driver {
615 5     5   10 my $self = shift;
616 5         12 $self->{send_using}->[0];
617             }
618              
619             sub _options {
620 10     10   18 my $self = shift;
621 10         15 my $options = $#{$self->{send_using}};
  10         19  
622 10         19 @{$self->{send_using}}[1 .. $options];
  10         85  
623             }
624              
625             =head2 mailer
626              
627             If you need to interact with it directly, the C method
628             returns the L mailer object that will be used to
629             send the email.
630              
631             Returns an L object, or dies if the driver is not
632             available.
633              
634             =cut
635              
636             sub mailer {
637 10     10 1 41 my $self = shift;
638 10 100       59 return $self->{mailer} if $self->{mailer};
639              
640 5         21 my $driver = $self->_driver;
641 5         44 $self->{mailer} = Email::Send->new( {
642             mailer => $driver,
643             mailer_args => [ $self->_options ],
644             } );
645 5 50       15705 unless ( $self->{mailer}->mailer_available($driver, $self->_options) ) {
646 0         0 Carp::croak("Driver $driver is not available");
647             }
648              
649 5         1123 $self->{mailer};
650             }
651              
652              
653              
654              
655              
656             #####################################################################
657             # Legacy compatibility
658              
659 0     0 0   sub To { shift->to(@_) }
660 0     0 0   sub From { shift->from(@_) }
661 0     0 0   sub CC { shift->cc(@_) }
662 0     0 0   sub BCC { shift->bcc(@_) }
663 0     0 0   sub Subject { shift->subject(@_) }
664 0     0 0   sub Email { shift->email(@_) }
665              
666             1;
667              
668             =head1 TO DO
669              
670             =over 4
671              
672             =item * Fix a number of bugs still likely to exist
673              
674             =item * Write more tests.
675              
676             =item * Add any additional small bit of automation that arn't too expensive
677              
678             =back
679              
680             =head1 SUPPORT
681              
682             All bugs should be filed via the bug tracker at
683              
684             L
685              
686             =head1 AUTHORS
687              
688             B: Ricardo Signes C
689              
690             Adam Kennedy Eadamk@cpan.orgE
691              
692             =head1 SEE ALSO
693              
694             L, L, L
695              
696             =head1 COPYRIGHT
697              
698             Copyright 2004 - 2008 Adam Kennedy.
699              
700             This program is free software; you can redistribute
701             it and/or modify it under the same terms as Perl itself.
702              
703             The full text of the license can be found in the
704             LICENSE file included with this module.
705              
706             =cut