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