package Contenido::Mail; use Net::SMTP; use MIME::Lite; use MIME::Base64; use Data::Dumper; use Contenido::Globals; sub new { my ($proto) = @_; my $class = ref($proto) || $proto; my $self = {}; $self->{enable} = $state->{email_enable}; if ( $self->{enable} ) { $self->{mailer} = $state->{email_mailer}; $self->{from} = $state->{email_from}; $self->{login} = $state->{email_auth_login}; $self->{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}; } } bless $self, $class; return $self; } sub send { return unless @_; my $self; if ( ref $_[0] eq 'Contenido::Mail' ) { $self = shift; } else { $self = Contenido::Mail->new; } my $opts = shift // {}; my $email = delete $opts->{email} // return undef; return unless ref $email && exists $email->{to} && $email->{subject} && $email->{body}; my $etype = delete $opts->{etype} // 'mixed'; my $debug = $state->development || $DEBUG || $opts->{debug} ? 1 : 0; my $subject = $email->{subject}; $subject = MIME::Base64::encode($subject); $subject =~ s/\s//sgi; $subject = '=?utf-8?B?'.$subject.'?='; 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 = shift @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; } } 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); $cc = $ecce; } $ccmail = join ', ', (@to, @{$email->{cc}}); } elsif ( exists $email->{cc} && $email->{cc} ) { my ($cce, $ecce) = $email->{cc} =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $email->{cc} =~ /<(.*?)>/ ? ('',$1) : ('',$email->{cc}); $ccmail = join ', ', (@to, $ecce); } elsif ( @to ) { $ccmail = join ', ', @to; } 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} ); } $mailer->mail( $emailfrom ); $mailer->to( $emailto ); $mailer->data; $mailer->datasend( $email_body ); $mailer->dataend; $mailer->quit; } else { warn "MAIL ERROR! Can't connect to Yandex SMTP\n"; } } } 1;