package Contenido::Mail;
use strict;
use warnings;
use Net::SMTP;
use MIME::Lite;
use MIME::Base64;
use Data::Dumper;
use parent 'Contenido::Accessor';
__PACKAGE__->mk_accessors(qw(enable mailer from login password server hello timeout ssl port));
use Contenido::Globals;
use Contenido::Email;
sub new {
my ($proto, $args) = @_;
my $class = ref($proto) || $proto;
$args //= {};
my $self = {};
bless $self, $class;
$self->enable( $state->{email_enable} );
if ( $self->enable ) {
$self->mailer( $state->{email_mailer} );
$self->from( $state->{email_from} );
$self->login( delete $args->{login} || $state->{email_auth_login} );
$self->password( delete $args->{password} || $state->{email_auth_password} );
if ( $self->mailer eq 'smtp' ) {
$self->server( $state->{email_smtp_server} );
$self->hello( $state->{email_smtp_hello} );
$self->timeout( $state->{email_smtp_timeout} );
$self->ssl( $state->{email_smtp_ssl} );
$self->port( $state->{email_smtp_port} );
}
}
warn Dumper $self if $DEBUG;
return $self;
}
sub send {
return unless @_;
my $self;
if ( ref $_[0] eq 'Contenido::Mail' ) {
$self = shift;
} elsif ( !ref $_[0] && $_[0] eq 'Contenido::Mail' ) {
my $class = shift;
$self = $class->new;
} else {
$self = Contenido::Mail->new;
}
my $opts = shift // {};
my $debug = $state->development || $DEBUG || $opts->{debug} ? 1 : 0;
my $email = delete $opts->{email} // return undef;
warn Dumper $email if $debug;
return unless ref $email && exists $email->{to} && $email->{subject} && $email->{body};
my $etype = delete $opts->{etype} // 'mixed';
my $subject = $email->{subject};
$subject = MIME::Base64::encode($subject);
$subject =~ s/\s//sgi;
$subject = '=?utf-8?B?'.$subject.'?=';
my $error;
my $emailfrom;
if ( $email->{from} ) {
my ($from, $efrom) = $email->{from} =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $email->{from} =~ /<(.*?)>/ ? ('',$1) : ('',$email->{from});
if ( $from ) {
$from = MIME::Base64::encode($from);
$from =~ s/\s+$//si;
$from = '=?utf-8?B?'.$from.'?=';
$emailfrom = $from.' <'.$efrom.'>';
} else {
$emailfrom = $efrom;
}
} elsif ( $state->{email_from} ) {
$emailfrom = $self->{from}
}
my ($emailto, @to);
if ( ref $email->{to} eq 'ARRAY' ) {
foreach my $tostr ( @{$email->{to}} ) {
my ($to, $eto) = $tostr =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $tostr =~ /<(.*?)>/ ? ('',$1) : ('',$tostr);
if ( $to ) {
$to = MIME::Base64::encode($to);
$to =~ s/\s+$//si;
$to = '=?utf-8?B?'.$to.'?=';
push @to, $to.' <'.$eto.'>';
} else {
push @to, '<'.$eto.'>';
}
}
$emailto = join ', ', @to;
} else {
my ($to, $eto) = $email->{to} =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $email->{to} =~ /<(.*?)>/ ? ('',$1) : ('',$email->{to});
if ( $to ) {
$to = MIME::Base64::encode($to);
$to =~ s/\s+$//si;
$to = '=?utf-8?B?'.$to.'?=';
$emailto = $to.' <'.$eto.'>';
} else {
$emailto = $eto;
}
@to = ($emailto);
}
my $ccmail;
if ( exists $email->{cc} && ref $email->{cc} eq 'ARRAY' ) {
foreach my $cc ( @{ $email->{cc}} ) {
my ($cce, $ecce) = $cc =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $cc =~ /<(.*?)>/ ? ('',$1) : ('',$cc);
$email->{cc} = ($cce ? $cce.' ' : '').'<'.$ecce.'>';
push @to, $ecce;
}
$ccmail = join ', ', @{$email->{cc}};
} elsif ( exists $email->{cc} && $email->{cc} ) {
my ($cce, $ecce) = $email->{cc} =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $email->{cc} =~ /<(.*?)>/ ? ('',$1) : ('',$email->{cc});
$ccmail = ($cce ? $cce.' ' : '').'<'.$ecce.'>';
push @to, $ecce;
}
my $body = $email->{body};
warn Dumper($email) if $debug;
my $dt = Contenido::DateTime->new;
$dt->set_locale('en_EN');
my $pdate = $dt->strftime("%a, %d %b %Y %H:%M:%S %z");
my $msg = MIME::Lite->new(
To => $emailto,
From => $emailfrom,
$ccmail ? ( Cc => $ccmail ) : (),
Subject => $subject,
# Encoding=> 'binary',
Date => $pdate,
Type => ($etype eq 'mixed' ? 'multipart/mixed' : $etype eq 'related' ? 'multipart/related;type="multipart/alternative";charset="utf-8"' : $etype),
);
$msg->attach(
'Type' => 'text/html;charset="utf-8"',
'Data' => $body,
'Disposition' => '',
);
my $email_body = $msg->as_string;
if ( $self->mailer eq 'smtp' ) {
my $mailer = Net::SMTP->new( $self->{server},
$self->{hello} ? (Hello => $self->{hello}) : (),
Port => $self->{port},
Timeout => $self->{timeout},
SSL => $self->{ssl},
Debug => $debug,
);
warn Dumper $mailer if $debug;
if ( ref $mailer ) {
if ( $self->{login} && $self->{password} ) {
$mailer->auth( $self->{login}, $self->{password} );
unless ( $mailer->ok ) {
$error = $mailer->message;
}
}
unless ( $error ) {
$mailer->mail( $emailfrom );
unless ( $mailer->ok ) {
$error = $mailer->message;
}
}
unless ( $error ) {
$mailer->to( @to );
unless ( $mailer->ok ) {
$error = $mailer->message;
}
}
unless ( $error ) {
$mailer->data;
$mailer->datasend( $email_body );
$mailer->dataend;
}
$mailer->quit;
} else {
$error = "MAIL ERROR! Can't create SMTP object";
warn "$error\n";
}
}
return $error;
}
sub add {
return unless @_;
my $self;
if ( ref $_[0] eq 'Contenido::Mail' ) {
$self = shift;
} elsif ( !ref $_[0] && $_[0] eq 'Contenido::Mail' ) {
my $class = shift;
$self = $class->new;
} else {
$self = Contenido::Mail->new;
}
my $opts = shift // {};
my $debug = $state->development || $DEBUG || $opts->{debug} ? 1 : 0;
my $email = delete $opts->{email} // return undef;
warn Dumper $email if $debug;
return unless ref $email && exists $email->{to} && $email->{subject} && $email->{body};
my $que = Contenido::Email->new( $keeper );
$que->status( 0 );
if ( ref $email->{to} eq 'ARRAY' ) {
my @to = grep { $_ } @{$email->{to}};
return unless @to;
$que->name( join ',', @to );
} else {
return unless $email->{to};
$que->name( $email->{to} );
}
if ( exists $email->{cc} && ref $email->{cc} eq 'ARRAY' ) {
$que->cc( join("\n", @{$email->{cc}}) );
} elsif ( exists $email->{cc} && $email->{cc} ) {
$que->cc( $email->{cc} );
}
$que->subject( $email->{subject} );
$que->body_html( $email->{body} );
if ( exists $email->{text} ) {
$que->body_text( $email->{text} );
}
if ( exists $email->{date} && ref $email->{date} eq 'DateTime' ) {
$que->dtime( $email->{date}->ymd('-').' '.$email->{date}->hms );
} elsif ( exists $email->{date} && $email->{date} ) {
my $dt;
eval{ $dt = Contenido::DateTime->new( postgres => $email->{date} ) };
if ( ref $dt ) {
$que->dtime( $dt->ymd('-').' '.$dt->hms );
}
} else {
my $now = Contenido::DateTime->new;
$que->dtime( $now->ymd('-').' '.$now->hms );
}
if ( $que->store ) {
return $que;
}
warn "Store failed!!!!\n" if $debug;
return undef;
}
1;