Line # Revision Author
1 740 ahitrov package Contenido::Mail;
2
3 use Net::SMTP;
4 use MIME::Lite;
5 use MIME::Base64;
6 use Data::Dumper;
7 use Contenido::Globals;
8
9 sub new {
10 my ($proto) = @_;
11 my $class = ref($proto) || $proto;
12 my $self = {};
13
14 $self->{enable} = $state->{email_enable};
15 if ( $self->{enable} ) {
16 $self->{mailer} = $state->{email_mailer};
17 $self->{from} = $state->{email_from};
18 $self->{login} = $state->{email_auth_login};
19 $self->{password} = $state->{email_auth_password};
20 if ( $self->{mailer} eq 'smtp' ) {
21 $self->{server} = $state->{email_smtp_server};
22 $self->{hello} = $state->{email_smtp_hello};
23 $self->{timeout} = $state->{email_smtp_timeout};
24 $self->{ssl} = $state->{email_smtp_ssl};
25 $self->{port} = $state->{email_smtp_port};
26 }
27 }
28
29 bless $self, $class;
30 return $self;
31 }
32
33 sub send {
34 return unless @_;
35 my $self;
36 if ( ref $_[0] eq 'Contenido::Mail' ) {
37 $self = shift;
38 } else {
39 $self = Contenido::Mail->new;
40 }
41
42 my $opts = shift // {};
43
44 my $email = delete $opts->{email} // return undef;
45 return unless ref $email && exists $email->{to} && $email->{subject} && $email->{body};
46
47 my $etype = delete $opts->{etype} // 'mixed';
48 my $debug = $state->development || $DEBUG || $opts->{debug} ? 1 : 0;
49
50 my $subject = $email->{subject};
51 $subject = MIME::Base64::encode($subject);
52 $subject =~ s/\s//sgi;
53 $subject = '=?utf-8?B?'.$subject.'?=';
54
55 my $emailfrom;
56 if ( $email->{from} ) {
57 my ($from, $efrom) = $email->{from} =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $email->{from} =~ /<(.*?)>/ ? ('',$1) : ('',$email->{from});
58 if ( $from ) {
59 $from = MIME::Base64::encode($from);
60 $from =~ s/\s+$//si;
61 $from = '=?utf-8?B?'.$from.'?=';
62 $emailfrom = $from.' <'.$efrom.'>';
63 } else {
64 $emailfrom = $efrom;
65 }
66 } elsif ( $state->{email_from} ) {
67 $emailfrom = $self->{from}
68 }
69
70 my ($emailto, @to);
71 if ( ref $email->{to} eq 'ARRAY' ) {
72 foreach my $tostr ( @{$email->{to}} ) {
73 my ($to, $eto) = $tostr =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $tostr =~ /<(.*?)>/ ? ('',$1) : ('',$tostr);
74 if ( $to ) {
75 $to = MIME::Base64::encode($to);
76 $to =~ s/\s+$//si;
77 $to = '=?utf-8?B?'.$to.'?=';
78 push @to, $to.' <'.$eto.'>';
79 } else {
80 push @to, $eto;
81 }
82 }
83 $emailto = shift @to;
84 } else {
85 my ($to, $eto) = $email->{to} =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $email->{to} =~ /<(.*?)>/ ? ('',$1) : ('',$email->{to});
86 if ( $to ) {
87 $to = MIME::Base64::encode($to);
88 $to =~ s/\s+$//si;
89 $to = '=?utf-8?B?'.$to.'?=';
90 $emailto = $to.' <'.$eto.'>';
91 } else {
92 $emailto = $eto;
93 }
94 }
95
96 my $ccmail;
97 if ( exists $email->{cc} && ref $email->{cc} eq 'ARRAY' ) {
98 foreach my $cc ( @{ $email->{cc}} ) {
99 my ($cce, $ecce) = $cc =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $cc =~ /<(.*?)>/ ? ('',$1) : ('',$cc);
100 $cc = $ecce;
101 }
102 $ccmail = join ', ', (@to, @{$email->{cc}});
103 } elsif ( exists $email->{cc} && $email->{cc} ) {
104 my ($cce, $ecce) = $email->{cc} =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $email->{cc} =~ /<(.*?)>/ ? ('',$1) : ('',$email->{cc});
105 $ccmail = join ', ', (@to, $ecce);
106 } elsif ( @to ) {
107 $ccmail = join ', ', @to;
108 }
109
110 my $body = $email->{body};
111 warn Dumper($email) if $debug;
112 my $dt = Contenido::DateTime->new;
113 $dt->set_locale('en_EN');
114 my $pdate = $dt->strftime("%a, %d %b %Y %H:%M:%S %z");
115 my $msg = MIME::Lite->new(
116 To => $emailto,
117 From => $emailfrom,
118 $ccmail ? ( Cc => $ccmail ) : (),
119 Subject => $subject,
120 # Encoding=> 'binary',
121 Date => $pdate,
122 Type => ($etype eq 'mixed' ? 'multipart/mixed' : $etype eq 'related' ? 'multipart/related;type="multipart/alternative";charset="utf-8"' : $etype),
123 );
124 $msg->attach(
125 'Type' => 'text/html;charset="utf-8"',
126 'Data' => $body,
127 'Disposition' => '',
128 );
129
130 my $email_body = $msg->as_string;
131 if ( $self->mailer eq 'smtp' ) {
132 my $mailer = Net::SMTP->new( $self->{server},
133 $self->{hello} ? (Hello => $self->{hello}) : (),
134 Port => $self->{port},
135 Timeout => $self->{timeout},
136 SSL => $self->{ssl},
137 Debug => $debug,
138 );
139 warn Dumper $mailer if $debug;
140 if ( ref $mailer ) {
141 if ( $self->{login} && $self->{password} ) {
142 $mailer->auth( $self->{login}, $self->{password} );
143 }
144 $mailer->mail( $emailfrom );
145 $mailer->to( $emailto );
146 $mailer->data;
147 $mailer->datasend( $email_body );
148 $mailer->dataend;
149 $mailer->quit;
150 } else {
151 warn "MAIL ERROR! Can't connect to Yandex SMTP\n";
152 }
153 }
154 }
155
156
157 1;