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