bumped version, fixed spelling errors
[catagits/Catalyst-View-Email.git] / lib / Catalyst / View / Email.pm
CommitLineData
529915ab 1package Catalyst::View::Email;
2
4e8cf755 3use Moose;
529915ab 4use Carp;
5
e512f6ca 6use Encode qw(encode decode);
2a6e60a4 7use Email::Sender::Simple qw/ sendmail /;
d8e2374d 8use Email::MIME::Creator;
4e8cf755 9extends 'Catalyst::View';
529915ab 10
cd6f4257 11our $VERSION = '0.25_01';
9ff9161d 12$VERSION = eval $VERSION;
d8e2374d 13
cbfdc762 14has 'mailer' => (
d8e2374d 15 is => 'rw',
16 isa => 'Str',
17 lazy => 1,
cbfdc762 18 default => sub { "sendmail" }
19);
20
21has '_mailer_obj' => (
22 is => 'rw',
2a6e60a4 23 isa => 'Email::Sender::Transport',
cbfdc762 24 lazy => 1,
25 builder => '_build_mailer_obj',
d8e2374d 26);
529915ab 27
4e8cf755 28has 'stash_key' => (
29 is => 'rw',
d8e2374d 30 isa => 'Str',
31 lazy => 1,
4e8cf755 32 default => sub { "email" }
33);
34
35has 'default' => (
36 is => 'rw',
d8e2374d 37 isa => 'HashRef',
38 default => sub { { content_type => 'text/plain' } },
4e8cf755 39 lazy => 1,
40);
41
4e8cf755 42has 'sender' => (
43 is => 'rw',
d8e2374d 44 isa => 'HashRef',
45 lazy => 1,
cbfdc762 46 default => sub { { mailer => shift->mailer } }
4e8cf755 47);
48
49has 'content_type' => (
50 is => 'rw',
502b5606 51 isa => 'Str',
52 default => sub { shift->default->{content_type} },
53 lazy => 1,
4e8cf755 54);
529915ab 55
56=head1 NAME
57
58Catalyst::View::Email - Send Email from Catalyst
59
60=head1 SYNOPSIS
61
4a44bcd3 62This module sends out emails from a stash key specified in the
529915ab 63configuration settings.
64
65=head1 CONFIGURATION
66
4a44bcd3 67WARNING: since version 0.10 the configuration options slightly changed!
68
ea115f9b 69Use the helper to create your View:
70
71 $ script/myapp_create.pl view Email Email
72
e512f6ca 73In your app configuration:
74
75 __PACKAGE__->config(
76 'View::Email' => {
77 # Where to look in the stash for the email information.
78 # 'email' is the default, so you don't have to specify it.
79 stash_key => 'email',
80 # Define the defaults for the mail
81 default => {
82 # Defines the default content type (mime type). Mandatory
83 content_type => 'text/plain',
84 # Defines the default charset for every MIME part with the
85 # content type text.
86 # According to RFC2049 a MIME part without a charset should
87 # be treated as US-ASCII by the mail client.
88 # If the charset is not set it won't be set for all MIME parts
89 # without an overridden one.
90 # Default: none
91 charset => 'utf-8'
6cbcc613 92 },
e512f6ca 93 # Setup how to send the email
502b5606 94 # all those options are passed directly to Email::Sender::Simple
e512f6ca 95 sender => {
502b5606 96 # if mailer doesn't start with Email::Sender::Simple::Transport::,
cbfdc762 97 # then this is prepended.
6cbcc613 98 mailer => 'SMTP',
502b5606 99 # mailer_args is passed directly into Email::Sender::Simple
e512f6ca 100 mailer_args => {
cbfdc762 101 host => 'smtp.example.com', # defaults to localhost
e512f6ca 102 username => 'username',
103 password => 'password',
104 }
98e5068b 105 }
106 }
e512f6ca 107 );
229f9fdd 108
4a44bcd3 109=head1 NOTE ON SMTP
229f9fdd 110
cbfdc762 111If you use SMTP and don't specify host, it will default to localhost and
4a44bcd3 112attempt delivery. This often means an email will sit in a queue and
113not be delivered.
529915ab 114
115=cut
116
529915ab 117=head1 SENDING EMAIL
118
4a44bcd3 119Sending email is just filling the stash and forwarding to the view:
529915ab 120
121 sub controller : Private {
122 my ( $self, $c ) = @_;
4a44bcd3 123
529915ab 124 $c->stash->{email} = {
4a44bcd3 125 to => 'jshirley@gmail.com',
126 cc => 'abraxxa@cpan.org',
98e5068b 127 bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
4a44bcd3 128 from => 'no-reply@foobar.com',
129 subject => 'I am a Catalyst generated email',
130 body => 'Body Body Body',
529915ab 131 };
4a44bcd3 132
133 $c->forward( $c->view('Email') );
529915ab 134 }
135
4a44bcd3 136Alternatively you can use a more raw interface and specify the headers as
137an array reference like it is passed to L<Email::MIME::Creator>.
138Note that you may also mix both syntaxes if you like ours better but need to
139specify additional header attributes.
140The attributes are appended to the header array reference without overwriting
141contained ones.
529915ab 142
143 $c->stash->{email} = {
144 header => [
4a44bcd3 145 To => 'jshirley@gmail.com',
146 Cc => 'abraxxa@cpan.org',
98e5068b 147 Bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
4a44bcd3 148 From => 'no-reply@foobar.com',
149 Subject => 'Note the capitalization differences',
529915ab 150 ],
151 body => qq{Ain't got no body, and nobody cares.},
152 # Or, send parts
153 parts => [
154 Email::MIME->create(
155 attributes => {
156 content_type => 'text/plain',
157 disposition => 'attachment',
158 charset => 'US-ASCII',
159 },
4a44bcd3 160 body => qq{Got a body, but didn't get ahead.},
529915ab 161 )
162 ],
163 };
164
2a175229 165=head1 HANDLING ERRORS
529915ab 166
4a44bcd3 167If the email fails to send, the view will die (throw an exception).
168After your forward to the view, it is a good idea to check for errors:
169
170 $c->forward( $c->view('Email') );
529915ab 171
529915ab 172 if ( scalar( @{ $c->error } ) ) {
173 $c->error(0); # Reset the error condition if you need to
4a44bcd3 174 $c->response->body('Oh noes!');
529915ab 175 } else {
4a44bcd3 176 $c->response->body('Email sent A-OK! (At least as far as we can tell)');
529915ab 177 }
178
ea115f9b 179=head1 USING TEMPLATES FOR EMAIL
529915ab 180
ea115f9b 181Now, it's no fun to just send out email using plain strings.
182Take a look at L<Catalyst::View::Email::Template> to see how you can use your
183favourite template engine to render the mail body.
529915ab 184
4a44bcd3 185=head1 METHODS
186
187=over 4
188
189=item new
190
502b5606 191Validates the base config and creates the L<Email::Sender::Simple> object for later use
4a44bcd3 192by process.
529915ab 193
194=cut
d8e2374d 195
4e8cf755 196sub BUILD {
197 my $self = shift;
529915ab 198
4e8cf755 199 my $stash_key = $self->stash_key;
d8e2374d 200 croak "$self stash_key isn't defined!"
201 if ( $stash_key eq '' );
529915ab 202
529915ab 203}
204
cbfdc762 205sub _build_mailer_obj {
502b5606 206 my ($self) = @_;
207 my $transport_class = ucfirst $self->sender->{mailer};
cbfdc762 208
cd6f4257 209 # borrowed from Email::Sender::Simple -- apeiron, 2010-01-26
502b5606 210 if ( $transport_class !~ /^Email::Sender::Transport::/ ) {
211 $transport_class = "Email::Sender::Transport::$transport_class";
212 }
cbfdc762 213
502b5606 214 Class::MOP::load_class($transport_class);
cbfdc762 215
502b5606 216 return $transport_class->new( $self->sender->{mailer_args} || {} );
cbfdc762 217}
218
4a44bcd3 219=item process($c)
11a0bf18 220
221The process method does the actual processing when the view is dispatched to.
222
502b5606 223This method sets up the email parts and hands off to L<Email::Sender::Simple> to handle
11a0bf18 224the actual email delivery.
225
226=cut
227
529915ab 228sub process {
229 my ( $self, $c ) = @_;
230
231 croak "Unable to send mail, bad mail configuration"
cbfdc762 232 unless $self->sender->{mailer};
529915ab 233
d8e2374d 234 my $email = $c->stash->{ $self->stash_key };
529915ab 235 croak "Can't send email without a valid email structure"
d8e2374d 236 unless $email;
237
238 # Default content type
239 if ( $self->content_type and not $email->{content_type} ) {
240 $email->{content_type} = $self->content_type;
241 }
242
243 my $header = $email->{header} || [];
244 push @$header, ( 'To' => delete $email->{to} )
245 if $email->{to};
246 push @$header, ( 'Cc' => delete $email->{cc} )
247 if $email->{cc};
248 push @$header, ( 'Bcc' => delete $email->{bcc} )
249 if $email->{bcc};
250 push @$header, ( 'From' => delete $email->{from} )
251 if $email->{from};
252 push @$header,
253 ( 'Subject' => Encode::encode( 'MIME-Header', delete $email->{subject} ) )
254 if $email->{subject};
255 push @$header, ( 'Content-type' => $email->{content_type} )
256 if $email->{content_type};
529915ab 257
258 my $parts = $email->{parts};
259 my $body = $email->{body};
d8e2374d 260
529915ab 261 unless ( $parts or $body ) {
262 croak "Can't send email without parts or body, check stash";
263 }
264
ab4326b4 265 my %mime = ( header => $header, attributes => {} );
529915ab 266
267 if ( $parts and ref $parts eq 'ARRAY' ) {
268 $mime{parts} = $parts;
d8e2374d 269 }
270 else {
529915ab 271 $mime{body} = $body;
272 }
ab4326b4 273
d8e2374d 274 $mime{attributes}->{content_type} = $email->{content_type}
275 if $email->{content_type};
276 if ( $mime{attributes}
277 and not $mime{attributes}->{charset}
278 and $self->{default}->{charset} )
279 {
280 $mime{attributes}->{charset} = $self->{default}->{charset};
281 }
282
d0e11256 283 my $message = $self->generate_message( $c, \%mime );
529915ab 284
d8e2374d 285 if ($message) {
cbfdc762 286 my $return = sendmail( $message, { transport => $self->_mailer_obj } );
d8e2374d 287
2a175229 288 # return is a Return::Value object, so this will stringify as the error
d8e2374d 289 # in the case of a failure.
95629d46 290 croak "$return" if !$return;
d8e2374d 291 }
292 else {
529915ab 293 croak "Unable to create message";
294 }
295}
296
4a44bcd3 297=item setup_attributes($c, $attr)
11a0bf18 298
4a44bcd3 299Merge attributes with the configured defaults. You can override this method to
11a0bf18 300return a structure to pass into L<generate_message> which subsequently
301passes the return value of this method to Email::MIME->create under the
302C<attributes> key.
303
304=cut
305
d8e2374d 306sub setup_attributes {
307 my ( $self, $c, $attrs ) = @_;
308
309 my $default_content_type = $self->default->{content_type};
310 my $default_charset = $self->default->{charset};
311
312 my $e_m_attrs = {};
313
314 if ( exists $attrs->{content_type}
315 && defined $attrs->{content_type}
316 && $attrs->{content_type} ne '' )
317 {
318 $c->log->debug( 'C::V::Email uses specified content_type '
319 . $attrs->{content_type}
320 . '.' )
321 if $c->debug;
322 $e_m_attrs->{content_type} = $attrs->{content_type};
323 }
324 elsif ( defined $default_content_type && $default_content_type ne '' ) {
325 $c->log->debug(
326 "C::V::Email uses default content_type $default_content_type.")
327 if $c->debug;
328 $e_m_attrs->{content_type} = $default_content_type;
329 }
330
331 if ( exists $attrs->{charset}
332 && defined $attrs->{charset}
333 && $attrs->{charset} ne '' )
334 {
335 $e_m_attrs->{charset} = $attrs->{charset};
336 }
337 elsif ( defined $default_charset && $default_charset ne '' ) {
338 $e_m_attrs->{charset} = $default_charset;
339 }
340
341 return $e_m_attrs;
342}
343
4a44bcd3 344=item generate_message($c, $attr)
11a0bf18 345
346Generate a message part, which should be an L<Email::MIME> object and return it.
347
348Takes the attributes, merges with the defaults as necessary and returns a
349message object.
350
351=cut
352
d0e11256 353sub generate_message {
0c8469c1 354 my ( $self, $c, $attr ) = @_;
43090696 355
d8e2374d 356 # setup the attributes (merge with defaultis)
502b5606 357 $attr->{attributes} = $self->setup_attributes( $c, $attr->{attributes} );
358 Email::MIME->create( %$attr );
43090696 359}
360
4a44bcd3 361=back
362
cbfdc762 363
e512f6ca 364=head1 TROUBLESHOOTING
365
366As with most things computer related, things break. Email even more so.
367Typically any errors are going to come from using SMTP as your sending method,
368which means that if you are having trouble the first place to look is at
cd6f4257 369L<Email::Sender::Transport::SMTP>. This module is just a wrapper for L<Email::Sender::Simple>,
e512f6ca 370so if you get an error on sending, it is likely from there anyway.
371
372If you are using SMTP and have troubles sending, whether it is authentication
373or a very bland "Can't send" message, make sure that you have L<Net::SMTP> and,
374if applicable, L<Net::SMTP::SSL> installed.
375
376It is very simple to check that you can connect via L<Net::SMTP>, and if you
377do have sending errors the first thing to do is to write a simple script
378that attempts to connect. If it works, it is probably something in your
379configuration so double check there. If it doesn't, well, keep modifying
380the script and/or your mail server configuration until it does!
381
529915ab 382=head1 SEE ALSO
383
384=head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
385
386=head2 L<Catalyst::Manual> - The Catalyst Manual
387
388=head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
389
390=head1 AUTHORS
391
392J. Shirley <jshirley@gmail.com>
393
4a44bcd3 394Alexander Hartmaier <abraxxa@cpan.org>
395
25650747 396=head1 CONTRIBUTORS
397
398(Thanks!)
399
94b4e4ff 400Matt S Trout
401
25650747 402Daniel Westermann-Clark
403
ea115f9b 404Simon Elliott <cpan@browsing.co.uk>
229f9fdd 405
95629d46 406Roman Filippov
407
b7b30250 408Lance Brown <lance@bearcircle.net>
409
6ca945f0 410Devin Austin <dhoss@cpan.org>
411
cbfdc762 412Chris Nehren <apeiron@cpan.org>
413
da1c5877 414=head1 COPYRIGHT
415
416Copyright (c) 2007 - 2009
417the Catalyst::View::Email L</AUTHORS> and L</CONTRIBUTORS>
418as listed above.
419
529915ab 420=head1 LICENSE
421
422This library is free software, you can redistribute it and/or modify it under
423the same terms as Perl itself.
424
425=cut
426
4271;