bumped version, fixed spelling errors
[catagits/Catalyst-View-Email.git] / lib / Catalyst / View / Email.pm
index ae9d77e..ef764bb 100644 (file)
@@ -1,20 +1,57 @@
 package Catalyst::View::Email;
 
-use warnings;
-use strict;
-
-use Class::C3;
+use Moose;
 use Carp;
 
 use Encode qw(encode decode);
-use Email::Send;
+use Email::Sender::Simple qw/ sendmail /;
 use Email::MIME::Creator;
+extends 'Catalyst::View';
+
+our $VERSION = '0.25_01';
+$VERSION = eval $VERSION;
 
-use parent 'Catalyst::View';
+has 'mailer' => (
+    is      => 'rw',
+    isa     => 'Str',
+    lazy    => 1,
+    default => sub { "sendmail" }
+);
+
+has '_mailer_obj' => (
+    is      => 'rw',
+    isa     => 'Email::Sender::Transport',
+    lazy    => 1,
+    builder => '_build_mailer_obj',
+);
+
+has 'stash_key' => (
+    is      => 'rw',
+    isa     => 'Str',
+    lazy    => 1,
+    default => sub { "email" }
+);
+
+has 'default' => (
+    is      => 'rw',
+    isa     => 'HashRef',
+    default => sub { { content_type => 'text/plain' } },
+    lazy    => 1,
+);
 
-our $VERSION = '0.13';
+has 'sender' => (
+    is      => 'rw',
+    isa     => 'HashRef',
+    lazy    => 1,
+    default => sub { { mailer => shift->mailer } }
+);
 
-__PACKAGE__->mk_accessors(qw/ mailer /);
+has 'content_type' => (
+    is      => 'rw',
+    isa     => 'Str',
+    default => sub { shift->default->{content_type} },
+    lazy    => 1,
+);
 
 =head1 NAME
 
@@ -54,12 +91,14 @@ In your app configuration:
                 charset => 'utf-8'
             },
             # Setup how to send the email
-            # all those options are passed directly to Email::Send
+            # all those options are passed directly to Email::Sender::Simple
             sender => {
+                # if mailer doesn't start with Email::Sender::Simple::Transport::,
+                # then this is prepended.
                 mailer => 'SMTP',
-                # mailer_args is passed directly into Email::Send 
+                # mailer_args is passed directly into Email::Sender::Simple 
                 mailer_args => {
-                    Host     => 'smtp.example.com', # defaults to localhost
+                    host     => 'smtp.example.com', # defaults to localhost
                     username => 'username',
                     password => 'password',
             }
@@ -69,19 +108,12 @@ In your app configuration:
 
 =head1 NOTE ON SMTP
 
-If you use SMTP and don't specify Host, it will default to localhost and
+If you use SMTP and don't specify host, it will default to localhost and
 attempt delivery. This often means an email will sit in a queue and
 not be delivered.
 
 =cut
 
-__PACKAGE__->config(
-    stash_key   => 'email',
-    default     => {
-        content_type    => 'text/plain',
-    },
-);
-
 =head1 SENDING EMAIL
 
 Sending email is just filling the stash and forwarding to the view:
@@ -156,53 +188,39 @@ favourite template engine to render the mail body.
 
 =item new
 
-Validates the base config and creates the L<Email::Send> object for later use
+Validates the base config and creates the L<Email::Sender::Simple> object for later use
 by process.
 
 =cut
 
-sub new {
-    my $self = shift->next::method(@_);
+sub BUILD {
+    my $self = shift;
 
-    my $stash_key = $self->{stash_key};
+    my $stash_key = $self->stash_key;
     croak "$self stash_key isn't defined!"
-        if ($stash_key eq '');
+      if ( $stash_key eq '' );
 
-    my $sender = Email::Send->new;
+}
 
-    if ( my $mailer = $self->{sender}->{mailer} ) {
-        croak "$mailer is not supported, see Email::Send"
-            unless $sender->mailer_available($mailer);
-        $sender->mailer($mailer);
-    }
-    else {
-        # Default case, run through the most likely options first.
-        for ( qw/SMTP Sendmail Qmail/ ) {
-            $sender->mailer($_) and last if $sender->mailer_available($_);
-        }
-    }
+sub _build_mailer_obj {
+    my ($self) = @_;
+    my $transport_class = ucfirst $self->sender->{mailer};
 
-    if ( my $args = $self->{sender}->{mailer_args} ) {
-        if ( ref $args eq 'HASH' ) {
-            $sender->mailer_args([ %$args ]);
-        }
-        elsif ( ref $args eq 'ARRAY' ) {
-            $sender->mailer_args($args);
-        } else {
-            croak "Invalid mailer_args specified, check pod for Email::Send!";
-        }
+    # borrowed from Email::Sender::Simple -- apeiron, 2010-01-26
+    if ( $transport_class !~ /^Email::Sender::Transport::/ ) {
+        $transport_class = "Email::Sender::Transport::$transport_class";
     }
 
-    $self->mailer($sender);
+    Class::MOP::load_class($transport_class);
 
-    return $self;
+    return $transport_class->new( $self->sender->{mailer_args} || {} );
 }
 
 =item process($c)
 
 The process method does the actual processing when the view is dispatched to.
 
-This method sets up the email parts and hands off to L<Email::Send> to handle
+This method sets up the email parts and hands off to L<Email::Sender::Simple> to handle
 the actual email delivery.
 
 =cut
@@ -211,34 +229,35 @@ sub process {
     my ( $self, $c ) = @_;
 
     croak "Unable to send mail, bad mail configuration"
-        unless $self->mailer;
+      unless $self->sender->{mailer};
 
-    my $email  = $c->stash->{$self->{stash_key}};
+    my $email = $c->stash->{ $self->stash_key };
     croak "Can't send email without a valid email structure"
-        unless $email;
+      unless $email;
 
     # Default content type
-    if ( exists $self->{content_type} and not $email->{content_type} ) {
-        $email->{content_type} = $self->{content_type};
+    if ( $self->content_type and not $email->{content_type} ) {
+        $email->{content_type} = $self->content_type;
     }
 
-    my $header  = $email->{header} || [];
-        push @$header, ('To' => delete $email->{to})
-            if $email->{to};
-        push @$header, ('Cc' => delete $email->{cc})
-            if $email->{cc};
-        push @$header, ('Bcc' => delete $email->{bcc})
-            if $email->{bcc};
-        push @$header, ('From' => delete $email->{from})
-            if $email->{from};
-        push @$header, ('Subject' => Encode::encode('MIME-Header', delete $email->{subject}))
-            if $email->{subject};
-        push @$header, ('Content-type' => $email->{content_type})
-            if $email->{content_type};
+    my $header = $email->{header} || [];
+    push @$header, ( 'To' => delete $email->{to} )
+      if $email->{to};
+    push @$header, ( 'Cc' => delete $email->{cc} )
+      if $email->{cc};
+    push @$header, ( 'Bcc' => delete $email->{bcc} )
+      if $email->{bcc};
+    push @$header, ( 'From' => delete $email->{from} )
+      if $email->{from};
+    push @$header,
+      ( 'Subject' => Encode::encode( 'MIME-Header', delete $email->{subject} ) )
+      if $email->{subject};
+    push @$header, ( 'Content-type' => $email->{content_type} )
+      if $email->{content_type};
 
     my $parts = $email->{parts};
     my $body  = $email->{body};
-   
+
     unless ( $parts or $body ) {
         croak "Can't send email without parts or body, check stash";
     }
@@ -247,26 +266,30 @@ sub process {
 
     if ( $parts and ref $parts eq 'ARRAY' ) {
         $mime{parts} = $parts;
-    } else {
+    }
+    else {
         $mime{body} = $body;
     }
 
-    $mime{attributes}->{content_type} = $email->{content_type} 
-        if $email->{content_type};
-    if ( $mime{attributes} and not $mime{attributes}->{charset} and
-         $self->{default}->{charset} )
+    $mime{attributes}->{content_type} = $email->{content_type}
+      if $email->{content_type};
+    if (    $mime{attributes}
+        and not $mime{attributes}->{charset}
+        and $self->{default}->{charset} )
     {
         $mime{attributes}->{charset} = $self->{default}->{charset};
     }
 
     my $message = $self->generate_message( $c, \%mime );
 
-    if ( $message ) {
-        my $return = $self->mailer->send($message);
+    if ($message) {
+        my $return = sendmail( $message, { transport => $self->_mailer_obj } );
+
         # return is a Return::Value object, so this will stringify as the error
-        # in the case of a failure.  
+        # in the case of a failure.
         croak "$return" if !$return;
-    } else {
+    }
+    else {
         croak "Unable to create message";
     }
 }
@@ -282,25 +305,36 @@ C<attributes> key.
 
 sub setup_attributes {
     my ( $self, $c, $attrs ) = @_;
-    
-    my $default_content_type    = $self->{default}->{content_type};
-    my $default_charset         = $self->{default}->{charset};
+
+    my $default_content_type = $self->default->{content_type};
+    my $default_charset      = $self->default->{charset};
 
     my $e_m_attrs = {};
 
-    if (exists $attrs->{content_type} && defined $attrs->{content_type} && $attrs->{content_type} ne '') {
-        $c->log->debug('C::V::Email uses specified content_type ' . $attrs->{content_type} . '.') if $c->debug;
+    if (   exists $attrs->{content_type}
+        && defined $attrs->{content_type}
+        && $attrs->{content_type} ne '' )
+    {
+        $c->log->debug( 'C::V::Email uses specified content_type '
+              . $attrs->{content_type}
+              . '.' )
+          if $c->debug;
         $e_m_attrs->{content_type} = $attrs->{content_type};
     }
-    elsif (defined $default_content_type && $default_content_type ne '') {
-        $c->log->debug("C::V::Email uses default content_type $default_content_type.") if $c->debug;
+    elsif ( defined $default_content_type && $default_content_type ne '' ) {
+        $c->log->debug(
+            "C::V::Email uses default content_type $default_content_type.")
+          if $c->debug;
         $e_m_attrs->{content_type} = $default_content_type;
     }
-   
-    if (exists $attrs->{charset} && defined $attrs->{charset} && $attrs->{charset} ne '') {
+
+    if (   exists $attrs->{charset}
+        && defined $attrs->{charset}
+        && $attrs->{charset} ne '' )
+    {
         $e_m_attrs->{charset} = $attrs->{charset};
     }
-    elsif (defined $default_charset && $default_charset ne '') {
+    elsif ( defined $default_charset && $default_charset ne '' ) {
         $e_m_attrs->{charset} = $default_charset;
     }
 
@@ -319,19 +353,20 @@ message object.
 sub generate_message {
     my ( $self, $c, $attr ) = @_;
 
-    # setup the attributes (merge with defaults)
-    $attr->{attributes} = $self->setup_attributes($c, $attr->{attributes});
-    return Email::MIME->create(%$attr);
+    # setup the attributes (merge with defaultis)
+    $attr->{attributes} = $self->setup_attributes( $c, $attr->{attributes} );
+    Email::MIME->create( %$attr );
 }
 
 =back
 
+
 =head1 TROUBLESHOOTING
 
 As with most things computer related, things break.  Email even more so.  
 Typically any errors are going to come from using SMTP as your sending method,
 which means that if you are having trouble the first place to look is at
-L<Email::Send::SMTP>.  This module is just a wrapper for L<Email::Send>,
+L<Email::Sender::Transport::SMTP>.  This module is just a wrapper for L<Email::Sender::Simple>,
 so if you get an error on sending, it is likely from there anyway.
 
 If you are using SMTP and have troubles sending, whether it is authentication
@@ -372,6 +407,10 @@ Roman Filippov
 
 Lance Brown <lance@bearcircle.net>
 
+Devin Austin <dhoss@cpan.org>
+
+Chris Nehren <apeiron@cpan.org>
+
 =head1 COPYRIGHT
 
 Copyright (c) 2007 - 2009