Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
610 florian 1
<?php
2
//
3
// +----------------------------------------------------------------------+
4
// | PHP Version 4                                                        |
5
// +----------------------------------------------------------------------+
6
// | Copyright (c) 1997-2003 The PHP Group                                |
7
// +----------------------------------------------------------------------+
8
// | This source file is subject to version 2.02 of the PHP license,      |
9
// | that is bundled with this package in the file LICENSE, and is        |
10
// | available at through the world-wide-web at                           |
11
// | http://www.php.net/license/2_02.txt.                                 |
12
// | If you did not receive a copy of the PHP license and are unable to   |
13
// | obtain it through the world-wide-web, please send a note to          |
14
// | license@php.net so we can mail you a copy immediately.               |
15
// +----------------------------------------------------------------------+
16
// | Authors: Chuck Hagenbuch <chuck@horde.org>                           |
17
// |          Jon Parise <jon@php.net>                                    |
18
// +----------------------------------------------------------------------+
19
 
20
/**
21
 * SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class.
22
 * @access public
23
 * @package Mail
24
 * @version $Revision: 1.1 $
25
 */
26
class Mail_smtp extends Mail {
27
 
28
    /**
29
     * SMTP connection object.
30
     *
31
     * @var object
32
     * @access private
33
     */
34
    var $_smtp = null;
35
 
36
    /**
37
     * The SMTP host to connect to.
38
     * @var string
39
     */
40
    var $host = 'localhost';
41
 
42
    /**
43
     * The port the SMTP server is on.
44
     * @var integer
45
     */
46
    var $port = 25;
47
 
48
    /**
49
     * Should SMTP authentication be used?
50
     *
51
     * This value may be set to true, false or the name of a specific
52
     * authentication method.
53
     *
54
     * If the value is set to true, the Net_SMTP package will attempt to use
55
     * the best authentication method advertised by the remote SMTP server.
56
     *
57
     * @var mixed
58
     */
59
    var $auth = false;
60
 
61
    /**
62
     * The username to use if the SMTP server requires authentication.
63
     * @var string
64
     */
65
    var $username = '';
66
 
67
    /**
68
     * The password to use if the SMTP server requires authentication.
69
     * @var string
70
     */
71
    var $password = '';
72
 
73
    /**
74
     * Hostname or domain that will be sent to the remote SMTP server in the
75
     * HELO / EHLO message.
76
     *
77
     * @var string
78
     */
79
    var $localhost = 'localhost';
80
 
81
    /**
82
     * SMTP connection timeout value.  NULL indicates no timeout.
83
     *
84
     * @var integer
85
     */
86
    var $timeout = null;
87
 
88
    /**
89
     * Whether to use VERP or not. If not a boolean, the string value
90
     * will be used as the VERP separators.
91
     *
92
     * @var mixed boolean or string
93
     */
94
    var $verp = false;
95
 
96
    /**
97
     * Turn on Net_SMTP debugging?
98
     *
99
     * @var boolean $debug
100
     */
101
    var $debug = false;
102
 
103
    /**
104
     * Indicates whether or not the SMTP connection should persist over
105
     * multiple calls to the send() method.
106
     *
107
     * @var boolean
108
     */
109
    var $persist = false;
110
 
111
    /**
112
     * Constructor.
113
     *
114
     * Instantiates a new Mail_smtp:: object based on the parameters
115
     * passed in. It looks for the following parameters:
116
     *     host        The server to connect to. Defaults to localhost.
117
     *     port        The port to connect to. Defaults to 25.
118
     *     auth        SMTP authentication.  Defaults to none.
119
     *     username    The username to use for SMTP auth. No default.
120
     *     password    The password to use for SMTP auth. No default.
121
     *     localhost   The local hostname / domain. Defaults to localhost.
122
     *     timeout     The SMTP connection timeout. Defaults to none.
123
     *     verp        Whether to use VERP or not. Defaults to false.
124
     *     debug       Activate SMTP debug mode? Defaults to false.
125
     *     persist     Should the SMTP connection persist?
126
     *
127
     * If a parameter is present in the $params array, it replaces the
128
     * default.
129
     *
130
     * @param array Hash containing any parameters different from the
131
     *              defaults.
132
     * @access public
133
     */
134
    function Mail_smtp($params)
135
    {
136
        if (isset($params['host'])) $this->host = $params['host'];
137
        if (isset($params['port'])) $this->port = $params['port'];
138
        if (isset($params['auth'])) $this->auth = $params['auth'];
139
        if (isset($params['username'])) $this->username = $params['username'];
140
        if (isset($params['password'])) $this->password = $params['password'];
141
        if (isset($params['localhost'])) $this->localhost = $params['localhost'];
142
        if (isset($params['timeout'])) $this->timeout = $params['timeout'];
143
        if (isset($params['verp'])) $this->verp = $params['verp'];
144
        if (isset($params['debug'])) $this->debug = (boolean)$params['debug'];
145
        if (isset($params['persist'])) $this->persist = (boolean)$params['persist'];
146
 
147
        register_shutdown_function(array(&$this, '_Mail_smtp'));
148
    }
149
 
150
    /**
151
     * Destructor implementation to ensure that we disconnect from any
152
     * potentially-alive persistent SMTP connections.
153
     */
154
    function _Mail_smtp()
155
    {
156
        $this->disconnect();
157
    }
158
 
159
    /**
160
     * Implements Mail::send() function using SMTP.
161
     *
162
     * @param mixed $recipients Either a comma-seperated list of recipients
163
     *              (RFC822 compliant), or an array of recipients,
164
     *              each RFC822 valid. This may contain recipients not
165
     *              specified in the headers, for Bcc:, resending
166
     *              messages, etc.
167
     *
168
     * @param array $headers The array of headers to send with the mail, in an
169
     *              associative array, where the array key is the
170
     *              header name (e.g., 'Subject'), and the array value
171
     *              is the header value (e.g., 'test'). The header
172
     *              produced from those values would be 'Subject:
173
     *              test'.
174
     *
175
     * @param string $body The full text of the message body, including any
176
     *               Mime parts, etc.
177
     *
178
     * @return mixed Returns true on success, or a PEAR_Error
179
     *               containing a descriptive error message on
180
     *               failure.
181
     * @access public
182
     */
183
    function send($recipients, $headers, $body)
184
    {
185
        include_once 'Net/SMTP.php';
186
 
187
        /* If we don't already have an SMTP object, create one. */
188
        if (is_object($this->_smtp) === false) {
189
            $this->_smtp =& new Net_SMTP($this->host, $this->port,
190
                                         $this->localhost);
191
 
192
            /* If we still don't have an SMTP object at this point, fail. */
193
            if (is_object($this->_smtp) === false) {
194
                return PEAR::raiseError('Failed to create a Net_SMTP object');
195
            }
196
 
197
            /* Configure the SMTP connection. */
198
            if ($this->debug) {
199
                $this->_smtp->setDebug(true);
200
            }
201
 
202
            /* Attempt to connect to the configured SMTP server. */
203
            if (PEAR::isError($res = $this->_smtp->connect($this->timeout))) {
204
                $error = $this->_error('Failed to connect to ' .
205
                                       $this->host . ':' . $this->port,
206
                                       $res);
207
                return PEAR::raiseError($error);
208
            }
209
 
210
            /* Attempt to authenticate if authentication has been enabled. */
211
            if ($this->auth) {
212
                $method = is_string($this->auth) ? $this->auth : '';
213
 
214
                if (PEAR::isError($res = $this->_smtp->auth($this->username,
215
                                                            $this->password,
216
                                                            $method))) {
217
                    $error = $this->_error("$method authentication failure",
218
                                           $res);
219
                    $this->_smtp->rset();
220
                    return PEAR::raiseError($error);
221
                }
222
            }
223
        }
224
 
225
        $headerElements = $this->prepareHeaders($headers);
226
        if (PEAR::isError($headerElements)) {
227
            $this->_smtp->rset();
228
            return $headerElements;
229
        }
230
        list($from, $textHeaders) = $headerElements;
231
 
232
        /* Since few MTAs are going to allow this header to be forged
233
         * unless it's in the MAIL FROM: exchange, we'll use
234
         * Return-Path instead of From: if it's set. */
235
        if (!empty($headers['Return-Path'])) {
236
            $from = $headers['Return-Path'];
237
        }
238
 
239
        if (!isset($from)) {
240
            $this->_smtp->rset();
241
            return PEAR::raiseError('No From: address has been provided');
242
        }
243
 
244
        $args['verp'] = $this->verp;
245
        if (PEAR::isError($res = $this->_smtp->mailFrom($from, $args))) {
246
            $error = $this->_error("Failed to set sender: $from", $res);
247
            $this->_smtp->rset();
248
            return PEAR::raiseError($error);
249
        }
250
 
251
        $recipients = $this->parseRecipients($recipients);
252
        if (PEAR::isError($recipients)) {
253
            $this->_smtp->rset();
254
            return $recipients;
255
        }
256
 
257
        foreach ($recipients as $recipient) {
258
            if (PEAR::isError($res = $this->_smtp->rcptTo($recipient))) {
259
                $error = $this->_error("Failed to add recipient: $recipient",
260
                                       $res);
261
                $this->_smtp->rset();
262
                return PEAR::raiseError($error);
263
            }
264
        }
265
 
266
        /* Send the message's headers and the body as SMTP data. */
267
        if (PEAR::isError($res = $this->_smtp->data("$textHeaders\r\n$body"))) {
268
            $error = $this->_error('Failed to send data', $res);
269
            $this->_smtp->rset();
270
            return PEAR::raiseError($error);
271
        }
272
 
273
        /* If persistent connections are disabled, destroy our SMTP object. */
274
        if ($this->persist === false) {
275
            $this->disconnect();
276
        }
277
 
278
        return true;
279
    }
280
 
281
    /**
282
     * Disconnect and destroy the current SMTP connection.
283
     *
284
     * @return boolean True if the SMTP connection no longer exists.
285
     *
286
     * @since  1.1.9
287
     * @access public
288
     */
289
    function disconnect()
290
    {
291
        /* If we have an SMTP object, disconnect and destroy it. */
292
        if (is_object($this->_smtp) && $this->_smtp->disconnect()) {
293
            $this->_smtp = null;
294
        }
295
 
296
        /* We are disconnected if we no longer have an SMTP object. */
297
        return ($this->_smtp === null);
298
    }
299
 
300
    /**
301
     * Build a standardized string describing the current SMTP error.
302
     *
303
     * @param string $text  Custom string describing the error context.
304
     * @param object $error Reference to the current PEAR_Error object.
305
     *
306
     * @return string       A string describing the current SMTP error.
307
     *
308
     * @since  1.1.7
309
     * @access private
310
     */
311
    function _error($text, &$error)
312
    {
313
        /* Split the SMTP response into a code and a response string. */
314
        list($code, $response) = $this->_smtp->getResponse();
315
 
316
        /* Build our standardized error string. */
317
        $msg = $text;
318
        $msg .= ' [SMTP: ' . $error->getMessage();
319
        $msg .= " (code: $code, response: $response)]";
320
 
321
        return $msg;
322
    }
323
}