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