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