Updates to mailer_args, pod -- support of hash and array of mailer_args. Version...
[catagits/Catalyst-View-Email.git] / lib / Catalyst / View / Email.pm
1 package Catalyst::View::Email;
2
3 use warnings;
4 use strict;
5
6 use Class::C3;
7 use Carp;
8
9 use Email::Send;
10 use Email::MIME::Creator;
11
12 use base qw|Catalyst::View|;
13
14 our $VERSION = '0.05';
15
16 __PACKAGE__->mk_accessors(qw(sender stash_key content_type mailer));
17
18 =head1 NAME
19
20 Catalyst::View::Email - Send Email from Catalyst
21
22 =head1 SYNOPSIS
23
24 This module simply sends out email from a stash key specified in the
25 configuration settings.
26
27 =head1 CONFIGURATION
28
29 In your app configuration (example in L<YAML>):
30
31     View::Email:
32         stash_key: email
33         content_type: text/plain 
34         sender:
35             method:     SMTP
36             # mailer_args is passed directly into Email::Send 
37             mailer_args:
38                 Host:       smtp.example.com # defaults to localhost
39                 username:   username
40                 password:   password
41
42 =head2 NOTE ON SMTP
43
44 If you use SMTP and don't specify Host, it will default to localhost and
45 attempt delivery.  This often times means an email will sit in a queue
46 somewhere and not be delivered.
47
48 =cut
49
50 __PACKAGE__->config(
51     stash_key => 'email',
52 );
53
54 =head1 SENDING EMAIL
55
56 In your controller, simply forward to the view after populating the C<stash_key>
57
58     sub controller : Private {
59         my ( $self, $c ) = @_;
60         $c->stash->{email} = {
61             to      => q{catalyst@rocksyoursocks.com},
62             from    => q{no-reply@socksthatarerocked.com},
63             subject => qq{Your Subject Here},
64             body    => qq{Body Body Body}
65         };
66         $c->forward('View::Email');
67     }
68
69 Alternatively, you can use a more raw interface, and specify the headers as
70 an array reference.
71
72     $c->stash->{email} = {
73         header => [
74             To      => 'foo@bar.com',
75             Subject => 'Note the capitalization differences'
76         ],
77         body => qq{Ain't got no body, and nobody cares.},
78         # Or, send parts
79         parts => [
80             Email::MIME->create(
81                 attributes => {
82                     content_type => 'text/plain',
83                     disposition  => 'attachment',
84                     charset      => 'US-ASCII',
85                 },
86                 body => qq{Got a body, but didn't get ahead.}
87             )
88         ],
89     };
90
91 =head1 HANDLING FAILURES
92
93 If the email fails to send, the view will die (throw an exception).  After
94 your forward to the view, it is a good idea to check for errors:
95     
96     $c->forward('View::Email');
97     if ( scalar( @{ $c->error } ) ) {
98         $c->error(0); # Reset the error condition if you need to
99         $c->res->body('Oh noes!');
100     } else {
101         $c->res->body('Email sent A-OK! (At least as far as we can tell)');
102     }
103
104 =head1 OTHER MAILERS
105
106 Now, it's no fun to just send out email using plain strings.  We also
107 have L<Catalyst::View::Email::Template> for use.  You can also toggle
108 this as being used by setting up your configuration to look like this:
109
110     View::Email:
111         default_view: TT
112
113 Then, Catalyst::View::Email will forward to your View::TT by default.
114
115 =cut
116
117 sub new {
118     my $self = shift->next::method(@_);
119
120     my ( $c, $arguments ) = @_;
121
122     my $mailer = Email::Send->new;
123
124     if ( my $method = $self->sender->{method} ) {
125         croak "$method is not supported, see Email::Send"
126             unless $mailer->mailer_available($method);
127         $mailer->mailer($method);
128     } else {
129         # Default case, run through the most likely options first.
130         for ( qw/SMTP Sendmail Qmail/ ) {
131             $mailer->mailer($_) and last if $mailer->mailer_available($_);
132         }
133     }
134
135     if ( my $args = $self->sender->{mailer_args} ) {
136         if ( ref $args eq 'HASH' ) {
137             $mailer->mailer_args([ %$args ]);
138         }
139         elsif ( ref $args eq 'ARRAY' ) {
140             $mailer->mailer_args($args);
141         } else {
142             croak "Invalid mailer_args specified, check pod for Email::Send!";
143         }
144     }
145
146     $self->mailer($mailer);
147
148     return $self;
149 }
150
151 sub process {
152     my ( $self, $c ) = @_;
153
154     croak "Unable to send mail, bad mail configuration"
155         unless $self->mailer;
156
157     my $email  = $c->stash->{$self->stash_key};
158     croak "Can't send email without a valid email structure"
159         unless $email;
160     
161     if ( $self->content_type ) {
162         $email->{content_type} ||= $self->content_type;
163     }
164
165     my $header  = $email->{header} || [];
166         push @$header, ('To' => delete $email->{to})
167             if $email->{to};
168         push @$header, ('From' => delete $email->{from})
169             if $email->{from};
170         push @$header, ('Subject' => delete $email->{subject})
171             if $email->{subject};
172         push @$header, ('Content-type' => delete $email->{content_type})
173             if $email->{content_type};
174
175     my $parts = $email->{parts};
176     my $body  = $email->{body};
177    
178     unless ( $parts or $body ) {
179         croak "Can't send email without parts or body, check stash";
180     }
181
182     my %mime = ( header => $header );
183
184     if ( $parts and ref $parts eq 'ARRAY' ) {
185         $mime{parts} = $parts;
186     } else {
187         $mime{body} = $body;
188     }
189
190     my $message = Email::MIME->create(%mime);
191
192     if ( $message ) {
193         $self->mailer->send($message);
194     } else {
195         croak "Unable to create message";
196     }
197 }
198
199 =head1 SEE ALSO
200
201 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
202
203 =head2 L<Catalyst::Manual> - The Catalyst Manual
204
205 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
206
207 =head1 AUTHORS
208
209 J. Shirley <jshirley@gmail.com>
210
211 =head1 CONTRIBUTORS
212
213 (Thanks!)
214
215 Matt S Trout
216
217 Daniel Westermann-Clark
218
219 Simon Elliott <cpan@browsing.co.uk> - ::Template
220
221 =head1 LICENSE
222
223 This library is free software, you can redistribute it and/or modify it under
224 the same terms as Perl itself.
225
226 =cut
227
228 1;