0.02 patch thanks to dwc.
[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.02';
15
16 __PACKAGE__->mk_accessors('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
39                 - username:   username
40                 - password:   password
41
42 =cut
43
44 __PACKAGE__->config(
45     stash_key => 'email',
46 );
47
48 =head1 SENDING EMAIL
49
50 In your controller, simply forward to the view after populating the C<stash_key>
51
52     sub controller : Private {
53         my ( $self, $c ) = @_;
54         $c->stash->{email} = {
55             to      => q{catalyst@rocksyoursocks.com},
56             from    => q{no-reply@socksthatarerocked.com},
57             subject => qq{Your Subject Here},
58             body    => qq{Body Body Body}
59         };
60         $c->forward('View::Email');
61     }
62
63 Alternatively, you can use a more raw interface, and specify the headers as
64 an array reference.
65
66     $c->stash->{email} = {
67         header => [
68             To      => 'foo@bar.com',
69             Subject => 'Note the capitalization differences'
70         ],
71         body => qq{Ain't got no body, and nobody cares.},
72         # Or, send parts
73         parts => [
74             Email::MIME->create(
75                 attributes => {
76                     content_type => 'text/plain',
77                     disposition  => 'attachment',
78                     charset      => 'US-ASCII',
79                 },
80                 body => qq{Got a body, but didn't get ahead.}
81             )
82         ],
83     };
84
85 =head1 HANDLING FAILURES
86
87 If the email fails to send, the view will die (throw an exception).  After
88 your forward to the view, it is a good idea to check for errors:
89     
90     $c->forward('View::Email');
91     if ( scalar( @{ $c->error } ) ) {
92         $c->error(0); # Reset the error condition if you need to
93         $c->res->body('Oh noes!');
94     } else {
95         $c->res->body('Email sent A-OK! (At least as far as we can tell)');
96     }
97
98 =head1 OTHER MAILERS
99
100 Now, it's no fun to just send out email using plain strings.  We also
101 have L<Catalyst::View::Email::Template> for use.  You can also toggle
102 this as being used by setting up your configuration to look like this:
103
104     View::Email:
105         default_view: TT
106
107 Then, Catalyst::View::Email will forward to your View::TT by default.
108
109 =cut
110
111 sub new {
112     my $self = shift->next::method(@_);
113
114     my ( $c, $arguments ) = @_;
115     $self->config($arguments);
116
117     my $mailer = Email::Send->new;
118
119     if ( my $method = $self->config->{sender}->{method} ) {
120         croak "$method is not supported, see Email::Send"
121             unless $mailer->mailer_available($method);
122         $mailer->mailer($method);
123     } else {
124         # Default case, run through the most likely options first.
125         for ( qw/SMTP Sendmail Qmail/ ) {
126             $mailer->mailer($_) and last if $mailer->mailer_available($_);
127         }
128     }
129
130     if ( $self->config->{sender}->{mailer_args} ) {
131         $mailer->mailer_args($self->config->{sender}->{mailer_args});
132     }
133
134     $self->mailer($mailer);
135
136     return $self;
137 }
138
139 sub process {
140     my ( $self, $c ) = @_;
141
142     croak "Unable to send mail, bad mail configuration"
143         unless $self->mailer;
144
145     my $email  = $c->stash->{$self->config->{stash_key}};
146     croak "Can't send email without a valid email structure"
147         unless $email;
148     
149     if ( $self->config->{content_type} ) {
150         $email->{content_type} ||= $self->config->{content_type};
151     }
152
153     my $header  = $email->{header} || [];
154         push @$header, ('To' => delete $email->{to})
155             if $email->{to};
156         push @$header, ('From' => delete $email->{from})
157             if $email->{from};
158         push @$header, ('Subject' => delete $email->{subject})
159             if $email->{subject};
160         push @$header, ('Content-type' => delete $email->{content_type})
161             if $email->{content_type};
162
163     my $parts = $email->{parts};
164     my $body  = $email->{body};
165    
166     unless ( $parts or $body ) {
167         croak "Can't send email without parts or body, check stash";
168     }
169
170     my %mime = ( header => $header );
171
172     if ( $parts and ref $parts eq 'ARRAY' ) {
173         $mime{parts} = $parts;
174     } else {
175         $mime{body} = $body;
176     }
177
178     my $message = Email::MIME->create(%mime);
179
180     if ( $message ) {
181         $self->mailer->send($message);
182     } else {
183         croak "Unable to create message";
184     }
185 }
186
187 =head1 SEE ALSO
188
189 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
190
191 =head2 L<Catalyst::Manual> - The Catalyst Manual
192
193 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
194
195 =head1 AUTHORS
196
197 J. Shirley <jshirley@gmail.com>
198
199 =head1 CONTRIBUTORS
200
201 (Thanks!)
202
203 Daniel Westermann-Clark
204
205 =head1 LICENSE
206
207 This library is free software, you can redistribute it and/or modify it under
208 the same terms as Perl itself.
209
210 =cut
211
212 1;