convert to Module::Install
[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
da20e8fa 11our $VERSION = '0.23';
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',
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
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
2a6e60a4 94 # all those options are passed directly to Email::Send
e512f6ca 95 sender => {
2a6e60a4 96 # if mailer doesn't start with Email::Sender::Transport::,
cbfdc762 97 # then this is prepended.
6cbcc613 98 mailer => 'SMTP',
2a6e60a4 99 # mailer_args is passed directly into Email::Send
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
2a6e60a4 191Validates the base config and creates the L<Email::Send> 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 {
206 my ($self) = @_;
207 my $transport_class = ucfirst $self->sender->{mailer};
208
2a6e60a4 209 # borrowed from Email::Sender::Simple -- apeiron, 2010-01-26
210 if ($transport_class !~ /^Email::Sender::Transport::/) {
211 $transport_class = "Email::Sender::Transport::$transport_class";
cbfdc762 212 }
213
214 Class::MOP::load_class($transport_class);
215
216 return $transport_class->new($self->sender->{mailer_args} || {});
217}
218
4a44bcd3 219=item process($c)
11a0bf18 220
221The process method does the actual processing when the view is dispatched to.
222
2a6e60a4 223This method sets up the email parts and hands off to L<Email::Send> 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)
357 $attr->{attributes} = $self->setup_attributes($c, $attr->{attributes});
ce1977b0 358 Email::MIME->create(
359 %$attr
360 );
43090696 361}
362
4a44bcd3 363=back
364
cbfdc762 365
e512f6ca 366=head1 TROUBLESHOOTING
367
368As with most things computer related, things break. Email even more so.
369Typically any errors are going to come from using SMTP as your sending method,
370which means that if you are having trouble the first place to look is at
2a6e60a4 371L<Email::Send::SMTP>. This module is just a wrapper for L<Email::Send>,
e512f6ca 372so if you get an error on sending, it is likely from there anyway.
373
374If you are using SMTP and have troubles sending, whether it is authentication
375or a very bland "Can't send" message, make sure that you have L<Net::SMTP> and,
376if applicable, L<Net::SMTP::SSL> installed.
377
378It is very simple to check that you can connect via L<Net::SMTP>, and if you
379do have sending errors the first thing to do is to write a simple script
380that attempts to connect. If it works, it is probably something in your
381configuration so double check there. If it doesn't, well, keep modifying
382the script and/or your mail server configuration until it does!
383
529915ab 384=head1 SEE ALSO
385
386=head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
387
388=head2 L<Catalyst::Manual> - The Catalyst Manual
389
390=head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
391
392=head1 AUTHORS
393
394J. Shirley <jshirley@gmail.com>
395
4a44bcd3 396Alexander Hartmaier <abraxxa@cpan.org>
397
25650747 398=head1 CONTRIBUTORS
399
400(Thanks!)
401
94b4e4ff 402Matt S Trout
403
25650747 404Daniel Westermann-Clark
405
ea115f9b 406Simon Elliott <cpan@browsing.co.uk>
229f9fdd 407
95629d46 408Roman Filippov
409
b7b30250 410Lance Brown <lance@bearcircle.net>
411
6ca945f0 412Devin Austin <dhoss@cpan.org>
413
cbfdc762 414Chris Nehren <apeiron@cpan.org>
415
da1c5877 416=head1 COPYRIGHT
417
418Copyright (c) 2007 - 2009
419the Catalyst::View::Email L</AUTHORS> and L</CONTRIBUTORS>
420as listed above.
421
529915ab 422=head1 LICENSE
423
424This library is free software, you can redistribute it and/or modify it under
425the same terms as Perl itself.
426
427=cut
428
4291;