root/branches/release-35/lib/MT/Mail.pm @ 1907

Revision 1907, 7.7 kB (checked in by fumiakiy, 20 months ago)

Use EmailAddressMain as default From address. BugId:67722

  • Property svn:keywords set to Author Date Id Revision
Line 
1# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
2# This program is distributed under the terms of the
3# GNU General Public License, version 2.
4#
5# $Id$
6
7package MT::Mail;
8
9use strict;
10
11use MT;
12use base qw( MT::ErrorHandler );
13use MT::I18N qw(encode_text);
14
15sub send {
16    my $class = shift;
17    my($hdrs_arg, $body) = @_;
18
19    local $hdrs_arg->{id} = $hdrs_arg->{id};
20    my $id = delete $hdrs_arg->{id};
21
22    my %hdrs = map { $_ => $hdrs_arg->{$_} } keys %$hdrs_arg;
23    foreach my $h (keys %hdrs) {
24        if (ref($hdrs{$h}) eq 'ARRAY') {
25            map { y/\n\r/  / } @{$hdrs{$h}};
26        } else {
27            $hdrs{$h} =~ y/\n\r/  / unless (ref($hdrs{$h}));
28        }
29    }
30   
31    my $mgr = MT->config;
32    my $xfer = $mgr->MailTransfer;
33
34    my $enc = $mgr->PublishCharset;
35    my $mail_enc = uc ($mgr->MailEncoding || $enc);
36
37
38    $body = encode_text($body, $enc, lc $mail_enc);
39
40    eval "require MIME::EncWords;";
41    unless ($@) {
42        foreach my $header (keys %hdrs) {
43            my $val = $hdrs{$header};
44
45            if (ref $val eq 'ARRAY') {
46                foreach (@$val) {
47                    if ((lc($mail_enc) ne 'iso-8859-1') || (m/[^[:print:]]/)) {
48                        if ($header =~ m/^(From|To|Reply|B?cc)/i) {
49                            if (m/^(.+?)\s*(<[^@>]+@[^>]+>)\s*$/) {
50                                $_ = MIME::EncWords::encode_mimeword(
51                                    encode_text($1, $enc, lc $mail_enc), 'b', lc $mail_enc) . ' ' . $2;
52                            }
53                        } elsif ($header !~ m/^(Content-Type|Content-Transfer-Encoding|MIME-Version)/i) {
54                            $_ = MIME::EncWords::encode_mimeword(
55                                    encode_text($_, $enc, lc $mail_enc), 'b', lc $mail_enc);
56                        }
57                    }
58                }
59            } else {
60                if ((lc($mail_enc) ne 'iso-8859-1') || ($val =~ /[^[:print:]]/)) {
61                    if ($header =~ m/^(From|To|Reply|B?cc)/i) {
62                        if ($val =~ m/^(.+?)\s*(<[^@>]+@[^>]+>)\s*$/) {
63                            $hdrs{$header} = MIME::EncWords::encode_mimeword(
64                                    encode_text($1, $enc, lc $mail_enc), 'b', lc $mail_enc) . ' ' . $2;
65                        }
66                    } elsif ($header !~ m/^(Content-Type|Content-Transfer-Encoding|MIME-Version)/i) {
67                        $hdrs{$header} = MIME::EncWords::encode_mimeword(
68                            encode_text($val, $enc, lc $mail_enc), 'b', lc $mail_enc);
69                    }
70                }
71            }
72        }
73    } else {
74        $hdrs{Subject} = encode_text($hdrs{Subject}, $enc, lc $mail_enc);
75        $hdrs{From} = encode_text($hdrs{From}, $enc, lc $mail_enc);
76    }
77    $hdrs{'Content-Type'} ||= qq(text/plain; charset=") . lc $mail_enc . q(");
78    $hdrs{'Content-Transfer-Encoding'} = ((lc $mail_enc) !~ m/utf-?8/) ? '7bit' : '8bit';
79    $hdrs{'MIME-Version'} ||= "1.0";
80
81    $hdrs{From} = $mgr->EmailAddressMain unless exists $hdrs{From};
82
83    return 1 unless
84        MT->run_callbacks('mail_filter', args => $hdrs_arg, headers => \%hdrs,
85            body => \$body, transfer => \$xfer, ( $id ? ( id => $id ) : () ) );
86
87    if ($xfer eq 'sendmail') {
88        return $class->_send_mt_sendmail(\%hdrs, $body, $mgr);
89    } elsif ($xfer eq 'smtp') {
90        return $class->_send_mt_smtp(\%hdrs, $body, $mgr);
91    } elsif ($xfer eq 'debug') {
92        return $class->_send_mt_debug(\%hdrs, $body, $mgr);
93    } else {
94        return $class->error(MT->translate(
95            "Unknown MailTransfer method '[_1]'", $xfer ));
96    }
97}
98
99use MT::Util qw(is_valid_email);
100
101sub _send_mt_debug {
102    my $class = shift;
103    my($hdrs, $body, $mgr) = @_;
104    $hdrs->{To} = $mgr->DebugEmailAddress
105        if (is_valid_email($mgr->DebugEmailAddress||''));
106    for my $key (keys %$hdrs) {
107        my @arr = ref($hdrs->{$key}) eq 'ARRAY' ?
108            @{ $hdrs->{$key} } : ($hdrs->{$key});
109        print STDERR map "$key: $_\n", @arr;
110    }
111    print STDERR "\n";
112    print STDERR $body;
113    1;
114}
115
116sub _send_mt_smtp {
117    my $class = shift;
118    my($hdrs, $body, $mgr) = @_;
119    eval { require Mail::Sendmail; };
120    return $class->error(MT->translate(
121        "Sending mail via SMTP requires that your server " .
122        "have Mail::Sendmail installed: [_1]", $@ )) if $@;
123    my %hdrs = %$hdrs;
124    $hdrs{Message} = $body;
125    $hdrs{Smtp} = $mgr->SMTPServer;
126    for my $h (qw( Cc Bcc )) {
127        if ($hdrs{$h}) {
128            $hdrs{$h} = join ', ', @{ $hdrs{$h} };
129        }
130    }
131    my $ret = Mail::Sendmail::sendmail(%hdrs);
132    $ret or return $class->error(MT->translate(
133        "Error sending mail: [_1]", $Mail::Sendmail::error ));
134    1;
135}
136
137my @Sendmail = qw( /usr/lib/sendmail /usr/sbin/sendmail /usr/ucblib/sendmail );
138sub _send_mt_sendmail {
139    my $class = shift;
140    my($hdrs, $body, $mgr) = @_;
141    $hdrs->{To} = $mgr->DebugEmailAddress
142        if (is_valid_email($mgr->DebugEmailAddress||''));
143    my $sm_loc;
144    for my $loc ($mgr->SendMailPath, @Sendmail) {
145        next unless $loc;
146        $sm_loc = $loc, last if -x $loc && !-d $loc;
147    }
148    return $class->error(MT->translate(
149        "You do not have a valid path to sendmail on your machine. " .
150        "Perhaps you should try using SMTP?" ))
151        unless $sm_loc;
152    local $SIG{PIPE} = { };
153    my $pid = open MAIL, '|-';
154    local $SIG{ALRM} = sub { CORE::exit() };
155    return unless defined $pid;
156    if (!$pid) {
157        exec $sm_loc, "-oi", "-t" or
158            return $class->error(MT->translate(
159                "Exec of sendmail failed: [_1]", "$!" ));
160    }
161    for my $key (keys %$hdrs) {
162        my @arr = ref($hdrs->{$key}) eq 'ARRAY' ?
163            @{ $hdrs->{$key} } : ($hdrs->{$key});
164        print MAIL map "$key: $_\n", @arr;
165    }
166    print MAIL "\n";
167    print MAIL $body;
168    close MAIL;
169    1;
170}
171
1721;
173__END__
174
175=head1 NAME
176
177MT::Mail - Movable Type mail sender
178
179=head1 SYNOPSIS
180
181    use MT::Mail;
182    my %head = ( To => 'foo@bar.com', Subject => 'My Subject' );
183    my $body = 'This is the body of the message.';
184    MT::Mail->send(\%head, $body)
185        or die MT::Mail->errstr;
186
187=head1 DESCRIPTION
188
189I<MT::Mail> is the Movable Type mail-sending interface. It can send mail
190through I<sendmail> (in several different default locations), through SMTP,
191or through a debugging interface that writes data to STDERR. You can set the
192method of sending mail through the F<mt.cfg> file by changing the value for
193the I<MailTransfer> setting to one of the following values: C<sendmail>,
194C<smtp>, or C<debug>.
195
196If you are using C<sendmail>, I<MT::Mail::send> looks for your I<sendmail>
197program in any of the following locations: F</usr/lib/sendmail>,
198F</usr/sbin/sendmail>, and F</usr/ucblib/sendmail>. If your I<sendmail> is at
199a different location, you can set it using the I<SendMailPath> directive.
200
201If you are using C<smtp>, I<MT::Mail::send> will by default use C<localhost>
202as the SMTP server. You can change this by setting the I<SMTPServer>
203directive.
204
205=head1 USAGE
206
207=head2 MT::Mail->send(\%headers, $body)
208
209Sends a mail message with the headers I<\%headers> and the message body
210I<$body>.
211
212The keys and values in I<\%headers> are passed directly in to the mail
213program or server, so you can use any valid mail header names as keys. If
214you need to supply a list of header values, specify the hash value as a
215reference to a list of the header values. For example:
216
217    %headers = ( Bcc => [ 'foo@bar.com', 'baz@quux.com' ] );
218
219If you wish the lines in I<$body> to be wrapped, you should do this yourself;
220it will not be done by I<send>.
221
222On success, I<send> returns true; on failure, it returns C<undef>, and the
223error message is in C<MT::Mail-E<gt>errstr>.
224
225=head1 AUTHOR & COPYRIGHT
226
227Please see the I<MT> manpage for author, copyright, and license information.
228
229=cut
Note: See TracBrowser for help on using the browser.