Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 469 lines (402 sloc) 14.986 kb
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
1 <?php
2
3 /*
4 +-----------------------------------------------------------------------+
5 | program/include/rcube_smtp.php |
6 | |
e019f2d0 » alecpl
2010-09-25 - s/RoundCube/Roundcube/
7 | This file is part of the Roundcube Webmail client |
f5e7b353 » thomascube
2011-01-12 Bumbed version; Roundcube development is not Switzerland only
8 | Copyright (C) 2005-2010, The Roundcube Dev Team |
7fe3811c » thomascube
2012-01-18 Changed license to GNU GPLv3+ with exceptions for skins and plugins
9 | |
10 | Licensed under the GNU General Public License version 3 or |
11 | any later version with exceptions for skins & plugins. |
12 | See the README file for a full license statement. |
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
13 | |
14 | PURPOSE: |
15 | Provide SMTP functionality using socket connections |
16 | |
17 +-----------------------------------------------------------------------+
18 | Author: Thomas Bruederli <roundcube@gmail.com> |
19 +-----------------------------------------------------------------------+
20 */
21
22 // define headers delimiter
23 define('SMTP_MIME_CRLF', "\r\n");
24
d062dbe1 » thomascube
2010-04-23 Add class docuumentation blocks and make phpdoc work again
25 /**
26 * Class to provide SMTP functionality using PEAR Net_SMTP
27 *
28 * @package Mail
29 * @author Thomas Bruederli <roundcube@gmail.com>
30 * @author Aleksander Machniak <alec@alec.pl>
31 */
32 class rcube_smtp
33 {
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
34
35 private $conn = null;
36 private $response;
37 private $error;
38
39
40 /**
41 * SMTP Connection and authentication
42 *
d1dd13ee » alecpl
2010-08-25 - Fix SMTP test in Installer (#1486952)
43 * @param string Server host
44 * @param string Server port
45 * @param string User name
46 * @param string Password
47 *
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
48 * @return bool Returns true on success, or false on error
49 */
63d4d611 » alecpl
2010-10-22 - Re-implemented SMTP proxy authorization support
50 public function connect($host=null, $port=null, $user=null, $pass=null)
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
51 {
be98dfc2 » alecpl
2012-04-16 - Replace some references to rcmail with rcube
52 $rcube = rcube::get_instance();
3875eb68 » alecpl
2011-11-24 - Add possibility to add SASL mechanisms for SMTP in smtp_connect hoo…
53
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
54 // disconnect/destroy $this->conn
55 $this->disconnect();
3875eb68 » alecpl
2011-11-24 - Add possibility to add SASL mechanisms for SMTP in smtp_connect hoo…
56
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
57 // reset error/response var
58 $this->error = $this->response = null;
3875eb68 » alecpl
2011-11-24 - Add possibility to add SASL mechanisms for SMTP in smtp_connect hoo…
59
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
60 // let plugins alter smtp connection config
be98dfc2 » alecpl
2012-04-16 - Replace some references to rcmail with rcube
61 $CONFIG = $rcube->plugins->exec_hook('smtp_connect', array(
62 'smtp_server' => $host ? $host : $rcube->config->get('smtp_server'),
63 'smtp_port' => $port ? $port : $rcube->config->get('smtp_port', 25),
64 'smtp_user' => $user ? $user : $rcube->config->get('smtp_user'),
65 'smtp_pass' => $pass ? $pass : $rcube->config->get('smtp_pass'),
66 'smtp_auth_cid' => $rcube->config->get('smtp_auth_cid'),
67 'smtp_auth_pw' => $rcube->config->get('smtp_auth_pw'),
68 'smtp_auth_type' => $rcube->config->get('smtp_auth_type'),
69 'smtp_helo_host' => $rcube->config->get('smtp_helo_host'),
70 'smtp_timeout' => $rcube->config->get('smtp_timeout'),
3875eb68 » alecpl
2011-11-24 - Add possibility to add SASL mechanisms for SMTP in smtp_connect hoo…
71 'smtp_auth_callbacks' => array(),
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
72 ));
73
1aceb9ce » alecpl
2012-04-16 - Framework refactoring (I hope it's the last one):
74 $smtp_host = rcube_utils::parse_host($CONFIG['smtp_server']);
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
75 // when called from Installer it's possible to have empty $smtp_host here
76 if (!$smtp_host) $smtp_host = 'localhost';
77 $smtp_port = is_numeric($CONFIG['smtp_port']) ? $CONFIG['smtp_port'] : 25;
78 $smtp_host_url = parse_url($smtp_host);
79
80 // overwrite port
81 if (isset($smtp_host_url['host']) && isset($smtp_host_url['port']))
82 {
83 $smtp_host = $smtp_host_url['host'];
84 $smtp_port = $smtp_host_url['port'];
85 }
86
87 // re-write smtp host
88 if (isset($smtp_host_url['host']) && isset($smtp_host_url['scheme']))
89 $smtp_host = sprintf('%s://%s', $smtp_host_url['scheme'], $smtp_host_url['host']);
90
2d08c50f » alecpl
2010-03-05 - Support/Require tls:// prefix in 'smtp_server' option for TLS conne…
91 // remove TLS prefix and set flag for use in Net_SMTP::auth()
92 if (preg_match('#^tls://#i', $smtp_host)) {
93 $smtp_host = preg_replace('#^tls://#i', '', $smtp_host);
94 $use_tls = true;
95 }
96
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
97 if (!empty($CONFIG['smtp_helo_host']))
98 $helo_host = $CONFIG['smtp_helo_host'];
99 else if (!empty($_SERVER['SERVER_NAME']))
100 $helo_host = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']);
101 else
102 $helo_host = 'localhost';
103
e9999199 » alecpl
2010-09-29 - Add Internationalized Domain Name (IDNA) support (#1483894)
104 // IDNA Support
1aceb9ce » alecpl
2012-04-16 - Framework refactoring (I hope it's the last one):
105 $smtp_host = rcube_utils::idn_to_ascii($smtp_host);
e9999199 » alecpl
2010-09-29 - Add Internationalized Domain Name (IDNA) support (#1483894)
106
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
107 $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
108
be98dfc2 » alecpl
2012-04-16 - Replace some references to rcmail with rcube
109 if ($rcube->config->get('smtp_debug'))
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
110 $this->conn->setDebug(true, array($this, 'debug_handler'));
a392125f » alecpl
2010-10-11 - Add SASL proxy authentication for SMTP (#1486693)
111
3875eb68 » alecpl
2011-11-24 - Add possibility to add SASL mechanisms for SMTP in smtp_connect hoo…
112 // register authentication methods
113 if (!empty($CONFIG['smtp_auth_callbacks']) && method_exists($this->conn, 'setAuthMethod')) {
114 foreach ($CONFIG['smtp_auth_callbacks'] as $callback) {
115 $this->conn->setAuthMethod($callback['name'], $callback['function'],
116 isset($callback['prepend']) ? $callback['prepend'] : true);
117 }
118 }
119
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
120 // try to connect to server and exit on failure
121 $result = $this->conn->connect($smtp_timeout);
63d4d611 » alecpl
2010-10-22 - Re-implemented SMTP proxy authorization support
122
123 if (PEAR::isError($result)) {
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
124 $this->response[] = "Connection failed: ".$result->getMessage();
125 $this->error = array('label' => 'smtpconnerror', 'vars' => array('code' => $this->conn->_code));
126 $this->conn = null;
127 return false;
128 }
129
462de2d2 » alecpl
2011-04-17 - PEAR::Net_SMTP 1.5.2, fixed timeout issue (#1487843)
130 // workaround for timeout bug in Net_SMTP 1.5.[0-1] (#1487843)
131 if (method_exists($this->conn, 'setTimeout')
132 && ($timeout = ini_get('default_socket_timeout'))
133 ) {
134 $this->conn->setTimeout($timeout);
135 }
136
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
137 $smtp_user = str_replace('%u', $_SESSION['username'], $CONFIG['smtp_user']);
be98dfc2 » alecpl
2012-04-16 - Replace some references to rcmail with rcube
138 $smtp_pass = str_replace('%p', $rcube->decrypt($_SESSION['password']), $CONFIG['smtp_pass']);
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
139 $smtp_auth_type = empty($CONFIG['smtp_auth_type']) ? NULL : $CONFIG['smtp_auth_type'];
e9999199 » alecpl
2010-09-29 - Add Internationalized Domain Name (IDNA) support (#1483894)
140
63d4d611 » alecpl
2010-10-22 - Re-implemented SMTP proxy authorization support
141 if (!empty($CONFIG['smtp_auth_cid'])) {
a392125f » alecpl
2010-10-11 - Add SASL proxy authentication for SMTP (#1486693)
142 $smtp_authz = $smtp_user;
63d4d611 » alecpl
2010-10-22 - Re-implemented SMTP proxy authorization support
143 $smtp_user = $CONFIG['smtp_auth_cid'];
144 $smtp_pass = $CONFIG['smtp_auth_pw'];
a392125f » alecpl
2010-10-11 - Add SASL proxy authentication for SMTP (#1486693)
145 }
146
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
147 // attempt to authenticate to the SMTP server
148 if ($smtp_user && $smtp_pass)
149 {
e9999199 » alecpl
2010-09-29 - Add Internationalized Domain Name (IDNA) support (#1483894)
150 // IDNA Support
e8d5bdc8 » alecpl
2011-02-03 - Fix IDNA support when IDN/INTL modules are in use (#1487742)
151 if (strpos($smtp_user, '@')) {
1aceb9ce » alecpl
2012-04-16 - Framework refactoring (I hope it's the last one):
152 $smtp_user = rcube_utils::idn_to_ascii($smtp_user);
e8d5bdc8 » alecpl
2011-02-03 - Fix IDNA support when IDN/INTL modules are in use (#1487742)
153 }
e9999199 » alecpl
2010-09-29 - Add Internationalized Domain Name (IDNA) support (#1483894)
154
a392125f » alecpl
2010-10-11 - Add SASL proxy authentication for SMTP (#1486693)
155 $result = $this->conn->auth($smtp_user, $smtp_pass, $smtp_auth_type, $use_tls, $smtp_authz);
2d08c50f » alecpl
2010-03-05 - Support/Require tls:// prefix in 'smtp_server' option for TLS conne…
156
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
157 if (PEAR::isError($result))
158 {
159 $this->error = array('label' => 'smtpautherror', 'vars' => array('code' => $this->conn->_code));
160 $this->response[] .= 'Authentication failure: ' . $result->getMessage() . ' (Code: ' . $result->getCode() . ')';
161 $this->reset();
d062dbe1 » thomascube
2010-04-23 Add class docuumentation blocks and make phpdoc work again
162 $this->disconnect();
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
163 return false;
164 }
165 }
166
167 return true;
168 }
169
170
171 /**
172 * Function for sending mail
173 *
174 * @param string Sender e-Mail address
175 *
176 * @param mixed Either a comma-seperated list of recipients
177 * (RFC822 compliant), or an array of recipients,
178 * each RFC822 valid. This may contain recipients not
179 * specified in the headers, for Bcc:, resending
180 * messages, etc.
181 * @param mixed The message headers to send with the mail
182 * Either as an associative array or a finally
183 * formatted string
91790e41 » alecpl
2010-02-09 - Fix attachment excessive memory use, support messages of any size (…
184 * @param mixed The full text of the message body, including any Mime parts
185 * or file handle
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
186 * @param array Delivery options (e.g. DSN request)
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
187 *
188 * @return bool Returns true on success, or false on error
189 */
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
190 public function send_mail($from, $recipients, &$headers, &$body, $opts=null)
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
191 {
192 if (!is_object($this->conn))
193 return false;
194
195 // prepare message headers as string
196 if (is_array($headers))
197 {
198 if (!($headerElements = $this->_prepare_headers($headers))) {
199 $this->reset();
200 return false;
201 }
202
203 list($from, $text_headers) = $headerElements;
204 }
205 else if (is_string($headers))
206 $text_headers = $headers;
207 else
208 {
209 $this->reset();
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
210 $this->response[] = "Invalid message headers";
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
211 return false;
212 }
213
214 // exit if no from address is given
215 if (!isset($from))
216 {
217 $this->reset();
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
218 $this->response[] = "No From address has been provided";
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
219 return false;
220 }
221
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
222 // RFC3461: Delivery Status Notification
223 if ($opts['dsn']) {
224 $exts = $this->conn->getServiceExtensions();
225
fb40f377 » alecpl
2011-10-07 - Ignore DSN request when it isn't supported by SMTP server (#1487800)
226 if (isset($exts['DSN'])) {
227 $from_params = 'RET=HDRS';
228 $recipient_params = 'NOTIFY=SUCCESS,FAILURE';
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
229 }
230 }
231
7f89041e » alecpl
2010-10-06 - Use empty envelope sender address for message disposition notificat…
232 // RFC2298.3: remove envelope sender address
233 if (preg_match('/Content-Type: multipart\/report/', $text_headers)
234 && preg_match('/report-type=disposition-notification/', $text_headers)
235 ) {
236 $from = '';
237 }
238
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
239 // set From: address
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
240 if (PEAR::isError($this->conn->mailFrom($from, $from_params)))
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
241 {
349a8e36 » alecpl
2010-06-08 - Add real SMTP error description to displayed error messages (#1485927)
242 $err = $this->conn->getResponse();
243 $this->error = array('label' => 'smtpfromerror', 'vars' => array(
244 'from' => $from, 'code' => $this->conn->_code, 'msg' => $err[1]));
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
245 $this->response[] = "Failed to set sender '$from'";
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
246 $this->reset();
247 return false;
248 }
249
250 // prepare list of recipients
251 $recipients = $this->_parse_rfc822($recipients);
252 if (PEAR::isError($recipients))
253 {
254 $this->error = array('label' => 'smtprecipientserror');
255 $this->reset();
256 return false;
257 }
258
259 // set mail recipients
260 foreach ($recipients as $recipient)
261 {
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
262 if (PEAR::isError($this->conn->rcptTo($recipient, $recipient_params))) {
349a8e36 » alecpl
2010-06-08 - Add real SMTP error description to displayed error messages (#1485927)
263 $err = $this->conn->getResponse();
264 $this->error = array('label' => 'smtptoerror', 'vars' => array(
265 'to' => $recipient, 'code' => $this->conn->_code, 'msg' => $err[1]));
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
266 $this->response[] = "Failed to add recipient '$recipient'";
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
267 $this->reset();
268 return false;
269 }
270 }
271
91790e41 » alecpl
2010-02-09 - Fix attachment excessive memory use, support messages of any size (…
272 if (is_resource($body))
273 {
274 // file handle
275 $data = $body;
276 $text_headers = preg_replace('/[\r\n]+$/', '', $text_headers);
277 } else {
278 // Concatenate headers and body so it can be passed by reference to SMTP_CONN->data
279 // so preg_replace in SMTP_CONN->quotedata will store a reference instead of a copy.
280 // We are still forced to make another copy here for a couple ticks so we don't really
281 // get to save a copy in the method call.
282 $data = $text_headers . "\r\n" . $body;
283
284 // unset old vars to save data and so we can pass into SMTP_CONN->data by reference.
285 unset($text_headers, $body);
286 }
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
287
288 // Send the message's headers and the body as SMTP data.
91790e41 » alecpl
2010-02-09 - Fix attachment excessive memory use, support messages of any size (…
289 if (PEAR::isError($result = $this->conn->data($data, $text_headers)))
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
290 {
b9d751df » alecpl
2010-03-12 - get better message for error in DATA
291 $err = $this->conn->getResponse();
14a4ac55 » alecpl
2010-05-26 - fix error message on SMTP oversize error (#1486754)
292 if (!in_array($err[0], array(354, 250, 221)))
b9d751df » alecpl
2010-03-12 - get better message for error in DATA
293 $msg = sprintf('[%d] %s', $err[0], $err[1]);
294 else
295 $msg = $result->getMessage();
296
297 $this->error = array('label' => 'smtperror', 'vars' => array('msg' => $msg));
f22ea7ba » alecpl
2010-10-07 - Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
298 $this->response[] = "Failed to send data";
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
299 $this->reset();
300 return false;
301 }
302
303 $this->response[] = join(': ', $this->conn->getResponse());
304 return true;
305 }
306
307
308 /**
309 * Reset the global SMTP connection
310 * @access public
311 */
312 public function reset()
313 {
314 if (is_object($this->conn))
315 $this->conn->rset();
316 }
317
318
319 /**
320 * Disconnect the global SMTP connection
321 * @access public
322 */
323 public function disconnect()
324 {
325 if (is_object($this->conn)) {
326 $this->conn->disconnect();
327 $this->conn = null;
328 }
329 }
330
331
332 /**
333 * This is our own debug handler for the SMTP connection
334 * @access public
335 */
336 public function debug_handler(&$smtp, $message)
337 {
be98dfc2 » alecpl
2012-04-16 - Replace some references to rcmail with rcube
338 rcube::write_log('smtp', preg_replace('/\r\n$/', '', $message));
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
339 }
340
341
342 /**
343 * Get error message
344 * @access public
345 */
346 public function get_error()
347 {
348 return $this->error;
349 }
350
351
352 /**
353 * Get server response messages array
354 * @access public
355 */
356 public function get_response()
357 {
358 return $this->response;
359 }
360
361
362 /**
363 * Take an array of mail headers and return a string containing
364 * text usable in sending a message.
365 *
366 * @param array $headers The array of headers to prepare, in an associative
367 * array, where the array key is the header name (ie,
368 * 'Subject'), and the array value is the header
369 * value (ie, 'test'). The header produced from those
370 * values would be 'Subject: test'.
371 *
372 * @return mixed Returns false if it encounters a bad address,
373 * otherwise returns an array containing two
374 * elements: Any From: address found in the headers,
375 * and the plain text version of the headers.
376 * @access private
377 */
378 private function _prepare_headers($headers)
379 {
380 $lines = array();
381 $from = null;
382
383 foreach ($headers as $key => $value)
384 {
385 if (strcasecmp($key, 'From') === 0)
386 {
387 $addresses = $this->_parse_rfc822($value);
388
389 if (is_array($addresses))
390 $from = $addresses[0];
391
392 // Reject envelope From: addresses with spaces.
6e0fdedf » alecpl
2011-11-28 - Use strpos() instead of strstr() when possible (#1488211)
393 if (strpos($from, ' ') !== false)
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
394 return false;
395
396 $lines[] = $key . ': ' . $value;
397 }
398 else if (strcasecmp($key, 'Received') === 0)
399 {
400 $received = array();
401 if (is_array($value))
402 {
403 foreach ($value as $line)
404 $received[] = $key . ': ' . $line;
405 }
406 else
407 {
408 $received[] = $key . ': ' . $value;
409 }
410
411 // Put Received: headers at the top. Spam detectors often
412 // flag messages with Received: headers after the Subject:
413 // as spam.
414 $lines = array_merge($received, $lines);
415 }
416 else
417 {
418 // If $value is an array (i.e., a list of addresses), convert
419 // it to a comma-delimited string of its elements (addresses).
420 if (is_array($value))
421 $value = implode(', ', $value);
422
423 $lines[] = $key . ': ' . $value;
424 }
425 }
413df054 » alecpl
2012-08-12 CS fixes (mostly tab -> spaces)
426
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
427 return array($from, join(SMTP_MIME_CRLF, $lines) . SMTP_MIME_CRLF);
428 }
429
430 /**
431 * Take a set of recipients and parse them, returning an array of
432 * bare addresses (forward paths) that can be passed to sendmail
433 * or an smtp server with the rcpt to: command.
434 *
435 * @param mixed Either a comma-seperated list of recipients
436 * (RFC822 compliant), or an array of recipients,
437 * each RFC822 valid.
438 *
439 * @return array An array of forward paths (bare addresses).
440 * @access private
441 */
442 private function _parse_rfc822($recipients)
443 {
444 // if we're passed an array, assume addresses are valid and implode them before parsing.
445 if (is_array($recipients))
446 $recipients = implode(', ', $recipients);
6d0ada30 » alecpl
2011-08-09 - Fix handling of email addresses with quoted local part (#1487939)
447
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
448 $addresses = array();
1aceb9ce » alecpl
2012-04-16 - Framework refactoring (I hope it's the last one):
449 $recipients = rcube_utils::explode_quoted_string(',', $recipients);
b579f42b » alecpl
2010-03-12 - fixes for proper handling of email addresses with form: "user"@doma…
450
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
451 reset($recipients);
452 while (list($k, $recipient) = each($recipients))
453 {
1aceb9ce » alecpl
2012-04-16 - Framework refactoring (I hope it's the last one):
454 $a = rcube_utils::explode_quoted_string(' ', $recipient);
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
455 while (list($k2, $word) = each($a))
456 {
b579f42b » alecpl
2010-03-12 - fixes for proper handling of email addresses with form: "user"@doma…
457 if (strpos($word, "@") > 0 && $word[strlen($word)-1] != '"')
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
458 {
459 $word = preg_replace('/^<|>$/', '', trim($word));
460 if (in_array($word, $addresses)===false)
461 array_push($addresses, $word);
462 }
463 }
464 }
6d0ada30 » alecpl
2011-08-09 - Fix handling of email addresses with quoted local part (#1487939)
465
2c3d81dd » alecpl
2009-07-21 - use simple rcube_smtp class
466 return $addresses;
467 }
468
469 }
Something went wrong with that request. Please try again.