ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
smtp.php
Go to the documentation of this file.
1 <?php
48 define('PEAR_MAIL_SMTP_ERROR_CREATE', 10000);
49 
51 define('PEAR_MAIL_SMTP_ERROR_CONNECT', 10001);
52 
54 define('PEAR_MAIL_SMTP_ERROR_AUTH', 10002);
55 
57 define('PEAR_MAIL_SMTP_ERROR_FROM', 10003);
58 
60 define('PEAR_MAIL_SMTP_ERROR_SENDER', 10004);
61 
63 define('PEAR_MAIL_SMTP_ERROR_RECIPIENT', 10005);
64 
66 define('PEAR_MAIL_SMTP_ERROR_DATA', 10006);
67 
74 class Mail_smtp extends Mail {
75 
82  var $_smtp = null;
83 
89  var $_extparams = array();
90 
95  var $host = 'localhost';
96 
101  var $port = 25;
102 
114  var $auth = false;
115 
120  var $username = '';
121 
126  var $password = '';
127 
134  var $localhost = 'localhost';
135 
141  var $timeout = null;
142 
148  var $debug = false;
149 
156  var $persist = false;
157 
165 
191  function Mail_smtp($params)
192  {
193  if (isset($params['host'])) $this->host = $params['host'];
194  if (isset($params['port'])) $this->port = $params['port'];
195  if (isset($params['auth'])) $this->auth = $params['auth'];
196  if (isset($params['username'])) $this->username = $params['username'];
197  if (isset($params['password'])) $this->password = $params['password'];
198  if (isset($params['localhost'])) $this->localhost = $params['localhost'];
199  if (isset($params['timeout'])) $this->timeout = $params['timeout'];
200  if (isset($params['debug'])) $this->debug = (bool)$params['debug'];
201  if (isset($params['persist'])) $this->persist = (bool)$params['persist'];
202  if (isset($params['pipelining'])) $this->pipelining = (bool)$params['pipelining'];
203 
204  // Deprecated options
205  if (isset($params['verp'])) {
206  $this->addServiceExtensionParameter('XVERP', is_bool($params['verp']) ? null : $params['verp']);
207  }
208 
209  register_shutdown_function(array(&$this, '_Mail_smtp'));
210  }
211 
216  function _Mail_smtp()
217  {
218  $this->disconnect();
219  }
220 
245  function send($recipients, $headers, $body)
246  {
247  /* If we don't already have an SMTP object, create one. */
248  $result = &$this->getSMTPObject();
249  if (PEAR::isError($result)) {
250  return $result;
251  }
252 
253  if (!is_array($headers)) {
254  return PEAR::raiseError('$headers must be an array');
255  }
256 
257  $this->_sanitizeHeaders($headers);
258 
259  $headerElements = $this->prepareHeaders($headers);
260  if (is_a($headerElements, 'PEAR_Error')) {
261  $this->_smtp->rset();
262  return $headerElements;
263  }
264  list($from, $textHeaders) = $headerElements;
265 
266  /* Since few MTAs are going to allow this header to be forged
267  * unless it's in the MAIL FROM: exchange, we'll use
268  * Return-Path instead of From: if it's set. */
269  if (!empty($headers['Return-Path'])) {
270  $from = $headers['Return-Path'];
271  }
272 
273  if (!isset($from)) {
274  $this->_smtp->rset();
275  return PEAR::raiseError('No From: address has been provided',
277  }
278 
279  $params = null;
280  if (!empty($this->_extparams)) {
281  foreach ($this->_extparams as $key => $val) {
282  $params .= ' ' . $key . (is_null($val) ? '' : '=' . $val);
283  }
284  }
285  if (PEAR::isError($res = $this->_smtp->mailFrom($from, ltrim($params)))) {
286  $error = $this->_error("Failed to set sender: $from", $res);
287  $this->_smtp->rset();
289  }
290 
291  $recipients = $this->parseRecipients($recipients);
292  if (is_a($recipients, 'PEAR_Error')) {
293  $this->_smtp->rset();
294  return $recipients;
295  }
296 
297  foreach ($recipients as $recipient) {
298  $res = $this->_smtp->rcptTo($recipient);
299  if (is_a($res, 'PEAR_Error')) {
300  $error = $this->_error("Failed to add recipient: $recipient", $res);
301  $this->_smtp->rset();
303  }
304  }
305 
306  /* Send the message's headers and the body as SMTP data. */
307  $res = $this->_smtp->data($textHeaders . "\r\n\r\n" . $body);
308  list(,$args) = $this->_smtp->getResponse();
309 
310  if (preg_match("/Ok: queued as (.*)/", $args, $queued)) {
311  $this->queued_as = $queued[1];
312  }
313 
314  /* we need the greeting; from it we can extract the authorative name of the mail server we've really connected to.
315  * ideal if we're connecting to a round-robin of relay servers and need to track which exact one took the email */
316  $this->greeting = $this->_smtp->getGreeting();
317 
318  if (is_a($res, 'PEAR_Error')) {
319  $error = $this->_error('Failed to send data', $res);
320  $this->_smtp->rset();
322  }
323 
324  /* If persistent connections are disabled, destroy our SMTP object. */
325  if ($this->persist === false) {
326  $this->disconnect();
327  }
328 
329  return true;
330  }
331 
342  function &getSMTPObject()
343  {
344  if (is_object($this->_smtp) !== false) {
345  return $this->_smtp;
346  }
347 
348  include_once 'Net/SMTP.php';
349  $this->_smtp = &new Net_SMTP($this->host,
350  $this->port,
351  $this->localhost);
352 
353  /* If we still don't have an SMTP object at this point, fail. */
354  if (is_object($this->_smtp) === false) {
355  return PEAR::raiseError('Failed to create a Net_SMTP object',
357  }
358 
359  /* Configure the SMTP connection. */
360  if ($this->debug) {
361  $this->_smtp->setDebug(true);
362  }
363 
364  /* Attempt to connect to the configured SMTP server. */
365  if (PEAR::isError($res = $this->_smtp->connect($this->timeout))) {
366  $error = $this->_error('Failed to connect to ' .
367  $this->host . ':' . $this->port,
368  $res);
370  }
371 
372  /* Attempt to authenticate if authentication has been enabled. */
373  if ($this->auth) {
374  $method = is_string($this->auth) ? $this->auth : '';
375 
376  if (PEAR::isError($res = $this->_smtp->auth($this->username,
377  $this->password,
378  $method))) {
379  $error = $this->_error("$method authentication failure",
380  $res);
381  $this->_smtp->rset();
383  }
384  }
385 
386  return $this->_smtp;
387  }
388 
398  function addServiceExtensionParameter($keyword, $value = null)
399  {
400  $this->_extparams[$keyword] = $value;
401  }
402 
411  function disconnect()
412  {
413  /* If we have an SMTP object, disconnect and destroy it. */
414  if (is_object($this->_smtp) && $this->_smtp->disconnect()) {
415  $this->_smtp = null;
416  }
417 
418  /* We are disconnected if we no longer have an SMTP object. */
419  return ($this->_smtp === null);
420  }
421 
433  function _error($text, &$error)
434  {
435  /* Split the SMTP response into a code and a response string. */
436  list($code, $response) = $this->_smtp->getResponse();
437 
438  /* Build our standardized error string. */
439  return $text
440  . ' [SMTP: ' . $error->getMessage()
441  . " (code: $code, response: $response)]";
442  }
443 
444 }