[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/horde/framework/Horde/Mime/ -> Mail.php (source)

   1  <?php
   2  /**
   3   * The Horde_Mime_Mail:: class wraps around the various MIME library classes
   4   * to provide a simple interface for creating and sending MIME messages.
   5   *
   6   * All content has to be passed UTF-8 encoded. The charset parameters is used
   7   * for the generated message only.
   8   *
   9   * Copyright 2007-2014 Horde LLC (http://www.horde.org/)
  10   *
  11   * See the enclosed file COPYING for license information (LGPL). If you
  12   * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  13   *
  14   * @author   Jan Schneider <jan@horde.org>
  15   * @category Horde
  16   * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
  17   * @package  Mime
  18   */
  19  class Horde_Mime_Mail
  20  {
  21      /**
  22       * The message headers.
  23       *
  24       * @var Horde_Mime_Headers
  25       */
  26      protected $_headers;
  27  
  28      /**
  29       * The base MIME part.
  30       *
  31       * @var Horde_Mime_Part
  32       */
  33      protected $_base;
  34  
  35      /**
  36       * The main body part.
  37       *
  38       * @var Horde_Mime_Part
  39       */
  40      protected $_body;
  41  
  42      /**
  43       * The main HTML body part.
  44       *
  45       * @var Horde_Mime_Part
  46       */
  47      protected $_htmlBody;
  48  
  49      /**
  50       * The message recipients.
  51       *
  52       * @var Horde_Mail_Rfc822_List
  53       */
  54      protected $_recipients;
  55  
  56      /**
  57       * Bcc recipients.
  58       *
  59       * @var string
  60       */
  61      protected $_bcc;
  62  
  63      /**
  64       * All MIME parts except the main body part.
  65       *
  66       * @var array
  67       */
  68      protected $_parts = array();
  69  
  70      /**
  71       * The Mail driver name.
  72       *
  73       * @link http://pear.php.net/Mail
  74       * @var string
  75       */
  76      protected $_mailer_driver = 'smtp';
  77  
  78      /**
  79       * The charset to use for the message.
  80       *
  81       * @var string
  82       */
  83      protected $_charset = 'UTF-8';
  84  
  85      /**
  86       * The Mail driver parameters.
  87       *
  88       * @link http://pear.php.net/Mail
  89       * @var array
  90       */
  91      protected $_mailer_params = array();
  92  
  93      /**
  94       * Constructor.
  95       *
  96       * @param array $params  A hash with basic message information. 'charset'
  97       *                       is the character set of the message.  'body' is
  98       *                       the message body. All other parameters are
  99       *                       assumed to be message headers.
 100       *
 101       * @throws Horde_Mime_Exception
 102       */
 103      public function __construct($params = array())
 104      {
 105          /* Set SERVER_NAME. */
 106          if (!isset($_SERVER['SERVER_NAME'])) {
 107              $_SERVER['SERVER_NAME'] = php_uname('n');
 108          }
 109  
 110          $this->_headers = new Horde_Mime_Headers();
 111  
 112          if (isset($params['charset'])) {
 113              $this->_charset = $params['charset'];
 114              unset($params['charset']);
 115          }
 116  
 117          if (isset($params['body'])) {
 118              $this->setBody($params['body'], $this->_charset);
 119              unset($params['body']);
 120          }
 121  
 122          $this->addHeaders($params);
 123  
 124          $this->clearRecipients();
 125      }
 126  
 127      /**
 128       * Adds several message headers at once.
 129       *
 130       * @param array $header    Hash with header names as keys and header
 131       *                         contents as values.
 132       *
 133       * @throws Horde_Mime_Exception
 134       */
 135      public function addHeaders($headers = array())
 136      {
 137          foreach ($headers as $header => $value) {
 138              $this->addHeader($header, $value);
 139          }
 140      }
 141  
 142      /**
 143       * Adds a message header.
 144       *
 145       * @param string $header      The header name.
 146       * @param string $value       The header value.
 147       * @param boolean $overwrite  If true, an existing header of the same name
 148       *                            is being overwritten; if false, multiple
 149       *                            headers are added; if null, the correct
 150       *                            behaviour is automatically chosen depending
 151       *                            on the header name.
 152       *
 153       * @throws Horde_Mime_Exception
 154       */
 155      public function addHeader($header, $value, $overwrite = null)
 156      {
 157          $lc_header = Horde_String::lower($header);
 158  
 159          if (is_null($overwrite) &&
 160              in_array($lc_header, $this->_headers->singleFields(true))) {
 161              $overwrite = true;
 162          }
 163  
 164          if ($overwrite) {
 165              $this->_headers->removeHeader($header);
 166          }
 167  
 168          if ($lc_header === 'bcc') {
 169              $this->_bcc = $value;
 170          } else {
 171              $this->_headers->addHeader($header, $value);
 172          }
 173      }
 174  
 175      /**
 176       * Removes a message header.
 177       *
 178       * @param string $header  The header name.
 179       */
 180      public function removeHeader($header)
 181      {
 182          if (Horde_String::lower($header) === 'bcc') {
 183              unset($this->_bcc);
 184          } else {
 185              $this->_headers->removeHeader($header);
 186          }
 187      }
 188  
 189      /**
 190       * Sets the message body text.
 191       *
 192       * @param string $body             The message content.
 193       * @param string $charset          The character set of the message.
 194       * @param boolean|integer $wrap    If true, wrap the message at column 76;
 195       *                                 If an integer wrap the message at that
 196       *                                 column. Don't use wrapping if sending
 197       *                                 flowed messages.
 198       */
 199      public function setBody($body, $charset = null, $wrap = false)
 200      {
 201          if (!$charset) {
 202              $charset = $this->_charset;
 203          }
 204          $body = Horde_String::convertCharset($body, 'UTF-8', $charset);
 205          if ($wrap) {
 206              $body = Horde_String::wrap($body, $wrap === true ? 76 : $wrap);
 207          }
 208          $this->_body = new Horde_Mime_Part();
 209          $this->_body->setType('text/plain');
 210          $this->_body->setCharset($charset);
 211          $this->_body->setContents($body);
 212          $this->_base = null;
 213      }
 214  
 215      /**
 216       * Sets the HTML message body text.
 217       *
 218       * @param string $body          The message content.
 219       * @param string $charset       The character set of the message.
 220       * @param boolean $alternative  If true, a multipart/alternative message is
 221       *                              created and the text/plain part is
 222       *                              generated automatically. If false, a
 223       *                              text/html message is generated.
 224       */
 225      public function setHtmlBody($body, $charset = null, $alternative = true)
 226      {
 227          if (!$charset) {
 228              $charset = $this->_charset;
 229          }
 230          $this->_htmlBody = new Horde_Mime_Part();
 231          $this->_htmlBody->setType('text/html');
 232          $this->_htmlBody->setCharset($charset);
 233          $this->_htmlBody->setContents($body);
 234          if ($alternative) {
 235              $this->setBody(Horde_Text_Filter::filter($body, 'Html2text', array('charset' => $charset, 'wrap' => false)), $charset);
 236          }
 237          $this->_base = null;
 238      }
 239  
 240      /**
 241       * Adds a message part.
 242       *
 243       * @param string $mime_type    The content type of the part.
 244       * @param string $content      The content of the part.
 245       * @param string $charset      The character set of the part.
 246       * @param string $disposition  The content disposition of the part.
 247       *
 248       * @return integer  The part number.
 249       */
 250      public function addPart($mime_type, $content, $charset = 'us-ascii',
 251                              $disposition = null)
 252      {
 253          $part = new Horde_Mime_Part();
 254          $part->setType($mime_type);
 255          $part->setCharset($charset);
 256          $part->setDisposition($disposition);
 257          $part->setContents($content);
 258          return $this->addMimePart($part);
 259      }
 260  
 261      /**
 262       * Adds a MIME message part.
 263       *
 264       * @param Horde_Mime_Part $part  A Horde_Mime_Part object.
 265       *
 266       * @return integer  The part number.
 267       */
 268      public function addMimePart($part)
 269      {
 270          $this->_parts[] = $part;
 271          return count($this->_parts) - 1;
 272      }
 273  
 274      /**
 275       * Sets the base MIME part.
 276       *
 277       * If the base part is set, any text bodies will be ignored when building
 278       * the message.
 279       *
 280       * @param Horde_Mime_Part $part  A Horde_Mime_Part object.
 281       */
 282      public function setBasePart($part)
 283      {
 284          $this->_base = $part;
 285      }
 286  
 287      /**
 288       * Adds an attachment.
 289       *
 290       * @param string $file     The path to the file.
 291       * @param string $name     The file name to use for the attachment.
 292       * @param string $type     The content type of the file.
 293       * @param string $charset  The character set of the part (only relevant for
 294       *                         text parts.
 295       *
 296       * @return integer  The part number.
 297       */
 298      public function addAttachment($file, $name = null, $type = null,
 299                                    $charset = 'us-ascii')
 300      {
 301          if (empty($name)) {
 302              $name = basename($file);
 303          }
 304  
 305          if (empty($type)) {
 306              $type = Horde_Mime_Magic::filenameToMime($file, false);
 307          }
 308  
 309          $num = $this->addPart($type, file_get_contents($file), $charset, 'attachment');
 310          $this->_parts[$num]->setName($name);
 311          return $num;
 312      }
 313  
 314      /**
 315       * Removes a message part.
 316       *
 317       * @param integer $part  The part number.
 318       */
 319      public function removePart($part)
 320      {
 321          if (isset($this->_parts[$part])) {
 322              unset($this->_parts[$part]);
 323          }
 324      }
 325  
 326      /**
 327       * Removes all (additional) message parts but leaves the body parts
 328       * untouched.
 329       */
 330      public function clearParts()
 331      {
 332          $this->_parts = array();
 333      }
 334  
 335      /**
 336       * Adds message recipients.
 337       *
 338       * Recipients specified by To:, Cc:, or Bcc: headers are added
 339       * automatically.
 340       *
 341       * @param string|array  List of recipients, either as a comma separated
 342       *                      list or as an array of email addresses.
 343       *
 344       * @throws Horde_Mime_Exception
 345       */
 346      public function addRecipients($recipients)
 347      {
 348          $this->_recipients->add($recipients);
 349      }
 350  
 351      /**
 352       * Removes message recipients.
 353       *
 354       * @param string|array  List of recipients, either as a comma separated
 355       *                      list or as an array of email addresses.
 356       *
 357       * @throws Horde_Mime_Exception
 358       */
 359      public function removeRecipients($recipients)
 360      {
 361          $this->_recipients->remove($recipients);
 362      }
 363  
 364      /**
 365       * Removes all message recipients.
 366       */
 367      public function clearRecipients()
 368      {
 369          $this->_recipients = new Horde_Mail_Rfc822_List();
 370      }
 371  
 372      /**
 373       * Sends this message.
 374       *
 375       * @param Mail $mailer     A Mail object.
 376       * @param boolean $resend  If true, the message id and date are re-used;
 377       *                         If false, they will be updated.
 378       * @param boolean $flowed  Send message in flowed text format.
 379       *
 380       * @throws Horde_Mime_Exception
 381       */
 382      public function send($mailer, $resend = false, $flowed = true)
 383      {
 384          /* Add mandatory headers if missing. */
 385          $has_header = $this->_headers->getValue('Message-ID');
 386          if (!$resend || !$has_header) {
 387              if ($has_header) {
 388                  $this->_headers->removeHeader('Message-ID');
 389              }
 390              $this->_headers->addMessageIdHeader();
 391          }
 392          if (!$this->_headers->getValue('User-Agent')) {
 393              $this->_headers->addUserAgentHeader();
 394          }
 395          $has_header = $this->_headers->getValue('Date');
 396          if (!$resend || !$has_header) {
 397              if ($has_header) {
 398                  $this->_headers->removeHeader('Date');
 399              }
 400              $this->_headers->addHeader('Date', date('r'));
 401          }
 402  
 403          if (isset($this->_base)) {
 404              $basepart = $this->_base;
 405          } else {
 406              /* Send in flowed format. */
 407              if ($flowed && !empty($this->_body)) {
 408                  $flowed = new Horde_Text_Flowed($this->_body->getContents(), $this->_body->getCharset());
 409                  $flowed->setDelSp(true);
 410                  $this->_body->setContentTypeParameter('format', 'flowed');
 411                  $this->_body->setContentTypeParameter('DelSp', 'Yes');
 412                  $this->_body->setContents($flowed->toFlowed());
 413              }
 414  
 415              /* Build mime message. */
 416              $body = new Horde_Mime_Part();
 417              if (!empty($this->_body) && !empty($this->_htmlBody)) {
 418                  $body->setType('multipart/alternative');
 419                  $this->_body->setDescription(Horde_Mime_Translation::t("Plaintext Version of Message"));
 420                  $body->addPart($this->_body);
 421                  $this->_htmlBody->setDescription(Horde_Mime_Translation::t("HTML Version of Message"));
 422                  $body->addPart($this->_htmlBody);
 423              } elseif (!empty($this->_htmlBody)) {
 424                  $body = $this->_htmlBody;
 425              } elseif (!empty($this->_body)) {
 426                  $body = $this->_body;
 427              }
 428              if (count($this->_parts)) {
 429                  $basepart = new Horde_Mime_Part();
 430                  $basepart->setType('multipart/mixed');
 431                  $basepart->isBasePart(true);
 432                  if ($body) {
 433                      $basepart->addPart($body);
 434                  }
 435                  foreach ($this->_parts as $mime_part) {
 436                      $basepart->addPart($mime_part);
 437                  }
 438              } else {
 439                  $basepart = $body;
 440                  $basepart->isBasePart(true);
 441              }
 442          }
 443          $basepart->setHeaderCharset($this->_charset);
 444  
 445          /* Build recipients. */
 446          $recipients = clone $this->_recipients;
 447          foreach (array('to', 'cc') as $header) {
 448              $recipients->add($this->_headers->getOb($header));
 449          }
 450          if ($this->_bcc) {
 451              $recipients->add($this->_bcc);
 452          }
 453  
 454          /* Trick Horde_Mime_Part into re-generating the message headers. */
 455          $this->_headers->removeHeader('MIME-Version');
 456  
 457          /* Send message. */
 458          $recipients->unique();
 459          $basepart->send($recipients->writeAddress(), $this->_headers, $mailer);
 460  
 461          /* Remember the basepart */
 462          $this->_base = $basepart;
 463      }
 464  
 465      /**
 466       * Get the raw email data sent by this object.
 467       *
 468       * @param  boolean $stream  If true, return a stream resource, otherwise
 469       *                          a string is returned.
 470       *
 471       * @return stream|string  The raw email data.
 472       * @since 2.4.0
 473       */
 474      public function getRaw($stream = true)
 475      {
 476          if ($stream) {
 477              $hdr = new Horde_Stream();
 478              $hdr->add($this->_headers->toString(), true);
 479              return Horde_Stream_Wrapper_Combine::getStream(array($hdr->stream, $this->getBasePart()->toString(array('stream' => true))));
 480          }
 481  
 482          return $this->_headers->toString() . $this->_getBasePart->toString();
 483      }
 484  
 485      /**
 486       * Return the base MIME part.
 487       *
 488       * @return Horde_Mime_Part
 489       */
 490      public function getBasePart()
 491      {
 492          if (empty($this->_base)) {
 493              throw new Horde_Mail_Exception('No base part set.');
 494          }
 495  
 496          return $this->_base;
 497      }
 498  
 499  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1