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