[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |