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