1<?php 2/** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to license@zend.com so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Mail 17 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 18 * @license http://framework.zend.com/license/new-bsd New BSD License 19 * @version $Id$ 20 */ 21 22 23/** 24 * @see Zend_Mail_Transport_Abstract 25 */ 26 27/** 28 * @see Zend_Mime 29 */ 30 31/** 32 * @see Zend_Mime_Message 33 */ 34 35/** 36 * @see Zend_Mime_Part 37 */ 38 39 40/** 41 * Class for sending an email. 42 * 43 * @category Zend 44 * @package Zend_Mail 45 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 46 * @license http://framework.zend.com/license/new-bsd New BSD License 47 */ 48class Zend_Mail extends Zend_Mime_Message 49{ 50 /**#@+ 51 * @access protected 52 */ 53 54 /** 55 * @var Zend_Mail_Transport_Abstract 56 * @static 57 */ 58 protected static $_defaultTransport = null; 59 60 /** 61 * @var array 62 * @static 63 */ 64 protected static $_defaultFrom; 65 66 /** 67 * @var array 68 * @static 69 */ 70 protected static $_defaultReplyTo; 71 72 /** 73 * Mail character set 74 * @var string 75 */ 76 protected $_charset = 'iso-8859-1'; 77 78 /** 79 * Mail headers 80 * @var array 81 */ 82 protected $_headers = array(); 83 84 /** 85 * Encoding of Mail headers 86 * @var string 87 */ 88 protected $_headerEncoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE; 89 90 /** 91 * From: address 92 * @var string 93 */ 94 protected $_from = null; 95 96 /** 97 * To: addresses 98 * @var array 99 */ 100 protected $_to = array(); 101 102 /** 103 * Array of all recipients 104 * @var array 105 */ 106 protected $_recipients = array(); 107 108 /** 109 * Reply-To header 110 * @var string 111 */ 112 protected $_replyTo = null; 113 114 /** 115 * Return-Path header 116 * @var string 117 */ 118 protected $_returnPath = null; 119 120 /** 121 * Subject: header 122 * @var string 123 */ 124 protected $_subject = null; 125 126 /** 127 * Date: header 128 * @var string 129 */ 130 protected $_date = null; 131 132 /** 133 * Message-ID: header 134 * @var string 135 */ 136 protected $_messageId = null; 137 138 /** 139 * text/plain MIME part 140 * @var false|Zend_Mime_Part 141 */ 142 protected $_bodyText = false; 143 144 /** 145 * text/html MIME part 146 * @var false|Zend_Mime_Part 147 */ 148 protected $_bodyHtml = false; 149 150 /** 151 * MIME boundary string 152 * @var string 153 */ 154 protected $_mimeBoundary = null; 155 156 /** 157 * Content type of the message 158 * @var string 159 */ 160 protected $_type = null; 161 162 /**#@-*/ 163 164 /** 165 * Flag: whether or not email has attachments 166 * @var boolean 167 */ 168 public $hasAttachments = false; 169 170 171 /** 172 * Sets the default mail transport for all following uses of 173 * Zend_Mail::send(); 174 * 175 * @todo Allow passing a string to indicate the transport to load 176 * @todo Allow passing in optional options for the transport to load 177 * @param Zend_Mail_Transport_Abstract $transport 178 */ 179 public static function setDefaultTransport(Zend_Mail_Transport_Abstract $transport) 180 { 181 self::$_defaultTransport = $transport; 182 } 183 184 /** 185 * Gets the default mail transport for all following uses of 186 * unittests 187 * 188 * @todo Allow passing a string to indicate the transport to load 189 * @todo Allow passing in optional options for the transport to load 190 */ 191 public static function getDefaultTransport() 192 { 193 return self::$_defaultTransport; 194 } 195 196 /** 197 * Clear the default transport property 198 */ 199 public static function clearDefaultTransport() 200 { 201 self::$_defaultTransport = null; 202 } 203 204 /** 205 * Public constructor 206 * 207 * @param string $charset 208 */ 209 public function __construct($charset = null) 210 { 211 if ($charset != null) { 212 $this->_charset = $charset; 213 } 214 } 215 216 /** 217 * Return charset string 218 * 219 * @return string 220 */ 221 public function getCharset() 222 { 223 return $this->_charset; 224 } 225 226 /** 227 * Set content type 228 * 229 * Should only be used for manually setting multipart content types. 230 * 231 * @param string $type Content type 232 * @return Zend_Mail Implements fluent interface 233 * @throws Zend_Mail_Exception for types not supported by Zend_Mime 234 */ 235 public function setType($type) 236 { 237 $allowed = array( 238 Zend_Mime::MULTIPART_ALTERNATIVE, 239 Zend_Mime::MULTIPART_MIXED, 240 Zend_Mime::MULTIPART_RELATED, 241 ); 242 if (!in_array($type, $allowed)) { 243 /** 244 * @see Zend_Mail_Exception 245 */ 246 throw new Zend_Mail_Exception('Invalid content type "' . $type . '"'); 247 } 248 249 $this->_type = $type; 250 return $this; 251 } 252 253 /** 254 * Get content type of the message 255 * 256 * @return string 257 */ 258 public function getType() 259 { 260 return $this->_type; 261 } 262 263 /** 264 * Set an arbitrary mime boundary for the message 265 * 266 * If not set, Zend_Mime will generate one. 267 * 268 * @param string $boundary 269 * @return Zend_Mail Provides fluent interface 270 */ 271 public function setMimeBoundary($boundary) 272 { 273 $this->_mimeBoundary = $boundary; 274 275 return $this; 276 } 277 278 /** 279 * Return the boundary string used for the message 280 * 281 * @return string 282 */ 283 public function getMimeBoundary() 284 { 285 return $this->_mimeBoundary; 286 } 287 288 /** 289 * Return encoding of mail headers 290 * 291 * @deprecated use {@link getHeaderEncoding()} instead 292 * @return string 293 */ 294 public function getEncodingOfHeaders() 295 { 296 return $this->getHeaderEncoding(); 297 } 298 299 /** 300 * Return the encoding of mail headers 301 * 302 * Either Zend_Mime::ENCODING_QUOTEDPRINTABLE or Zend_Mime::ENCODING_BASE64 303 * 304 * @return string 305 */ 306 public function getHeaderEncoding() 307 { 308 return $this->_headerEncoding; 309 } 310 311 /** 312 * Set the encoding of mail headers 313 * 314 * @deprecated Use {@link setHeaderEncoding()} instead. 315 * @param string $encoding 316 * @return Zend_Mail 317 */ 318 public function setEncodingOfHeaders($encoding) 319 { 320 return $this->setHeaderEncoding($encoding); 321 } 322 323 /** 324 * Set the encoding of mail headers 325 * 326 * @param string $encoding Zend_Mime::ENCODING_QUOTEDPRINTABLE or 327 * Zend_Mime::ENCODING_BASE64 328 * @return Zend_Mail Provides fluent interface 329 * @throws Zend_Mail_Exception 330 */ 331 public function setHeaderEncoding($encoding) 332 { 333 $allowed = array( 334 Zend_Mime::ENCODING_BASE64, 335 Zend_Mime::ENCODING_QUOTEDPRINTABLE 336 ); 337 if (!in_array($encoding, $allowed)) { 338 /** 339 * @see Zend_Mail_Exception 340 */ 341 throw new Zend_Mail_Exception('Invalid encoding "' . $encoding . '"'); 342 } 343 $this->_headerEncoding = $encoding; 344 345 return $this; 346 } 347 348 /** 349 * Sets the text body for the message. 350 * 351 * @param string $txt 352 * @param string $charset 353 * @param string $encoding 354 * @return Zend_Mail Provides fluent interface 355 */ 356 public function setBodyText($txt, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE) 357 { 358 if ($charset === null) { 359 $charset = $this->_charset; 360 } 361 362 $mp = new Zend_Mime_Part($txt); 363 $mp->encoding = $encoding; 364 $mp->type = Zend_Mime::TYPE_TEXT; 365 $mp->disposition = Zend_Mime::DISPOSITION_INLINE; 366 $mp->charset = $charset; 367 368 $this->_bodyText = $mp; 369 370 return $this; 371 } 372 373 /** 374 * Return text body Zend_Mime_Part or string 375 * 376 * @param bool $textOnly Whether to return just the body text content or 377 * the MIME part; defaults to false, the MIME part 378 * @return false|Zend_Mime_Part|string 379 */ 380 public function getBodyText($textOnly = false) 381 { 382 if ($textOnly && $this->_bodyText) { 383 $body = $this->_bodyText; 384 return $body->getContent(); 385 } 386 387 return $this->_bodyText; 388 } 389 390 /** 391 * Sets the HTML body for the message 392 * 393 * @param string $html 394 * @param string $charset 395 * @param string $encoding 396 * @return Zend_Mail Provides fluent interface 397 */ 398 public function setBodyHtml($html, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE) 399 { 400 if ($charset === null) { 401 $charset = $this->_charset; 402 } 403 404 $mp = new Zend_Mime_Part($html); 405 $mp->encoding = $encoding; 406 $mp->type = Zend_Mime::TYPE_HTML; 407 $mp->disposition = Zend_Mime::DISPOSITION_INLINE; 408 $mp->charset = $charset; 409 410 $this->_bodyHtml = $mp; 411 412 return $this; 413 } 414 415 /** 416 * Return Zend_Mime_Part representing body HTML 417 * 418 * @param bool $htmlOnly Whether to return the body HTML only, or the MIME part; defaults to false, the MIME part 419 * @return false|Zend_Mime_Part|string 420 */ 421 public function getBodyHtml($htmlOnly = false) 422 { 423 if ($htmlOnly && $this->_bodyHtml) { 424 $body = $this->_bodyHtml; 425 return $body->getContent(); 426 } 427 428 return $this->_bodyHtml; 429 } 430 431 /** 432 * Adds an existing attachment to the mail message 433 * 434 * @param Zend_Mime_Part $attachment 435 * @return Zend_Mail Provides fluent interface 436 */ 437 public function addAttachment(Zend_Mime_Part $attachment) 438 { 439 $this->addPart($attachment); 440 $this->hasAttachments = true; 441 442 return $this; 443 } 444 445 /** 446 * Creates a Zend_Mime_Part attachment 447 * 448 * Attachment is automatically added to the mail object after creation. The 449 * attachment object is returned to allow for further manipulation. 450 * 451 * @param string $body 452 * @param string $mimeType 453 * @param string $disposition 454 * @param string $encoding 455 * @param string $filename OPTIONAL A filename for the attachment 456 * @return Zend_Mime_Part Newly created Zend_Mime_Part object (to allow 457 * advanced settings) 458 */ 459 public function createAttachment($body, 460 $mimeType = Zend_Mime::TYPE_OCTETSTREAM, 461 $disposition = Zend_Mime::DISPOSITION_ATTACHMENT, 462 $encoding = Zend_Mime::ENCODING_BASE64, 463 $filename = null) 464 { 465 466 $mp = new Zend_Mime_Part($body); 467 $mp->encoding = $encoding; 468 $mp->type = $mimeType; 469 $mp->disposition = $disposition; 470 $mp->filename = $filename; 471 472 $this->addAttachment($mp); 473 474 return $mp; 475 } 476 477 /** 478 * Return a count of message parts 479 * 480 * @return integer 481 */ 482 public function getPartCount() 483 { 484 return count($this->_parts); 485 } 486 487 /** 488 * Encode header fields 489 * 490 * Encodes header content according to RFC1522 if it contains non-printable 491 * characters. 492 * 493 * @param string $value 494 * @return string 495 */ 496 protected function _encodeHeader($value) 497 { 498 if (Zend_Mime::isPrintable($value) === false) { 499 if ($this->getHeaderEncoding() === Zend_Mime::ENCODING_QUOTEDPRINTABLE) { 500 $value = Zend_Mime::encodeQuotedPrintableHeader($value, $this->getCharset(), Zend_Mime::LINELENGTH, Zend_Mime::LINEEND); 501 } else { 502 $value = Zend_Mime::encodeBase64Header($value, $this->getCharset(), Zend_Mime::LINELENGTH, Zend_Mime::LINEEND); 503 } 504 } 505 506 return $value; 507 } 508 509 /** 510 * Add a header to the message 511 * 512 * Adds a header to this message. If append is true and the header already 513 * exists, raises a flag indicating that the header should be appended. 514 * 515 * @param string $headerName 516 * @param string $value 517 * @param bool $append 518 */ 519 protected function _storeHeader($headerName, $value, $append = false) 520 { 521 if (isset($this->_headers[$headerName])) { 522 $this->_headers[$headerName][] = $value; 523 } else { 524 $this->_headers[$headerName] = array($value); 525 } 526 527 if ($append) { 528 $this->_headers[$headerName]['append'] = true; 529 } 530 531 } 532 533 /** 534 * Clear header from the message 535 * 536 * @param string $headerName 537 * @deprecated use public method directly 538 */ 539 protected function _clearHeader($headerName) 540 { 541 $this->clearHeader($headerName); 542 } 543 544 /** 545 * Helper function for adding a recipient and the corresponding header 546 * 547 * @param string $headerName 548 * @param string $email 549 * @param string $name 550 */ 551 protected function _addRecipientAndHeader($headerName, $email, $name) 552 { 553 $email = $this->_filterEmail($email); 554 $name = $this->_filterName($name); 555 // prevent duplicates 556 $this->_recipients[$email] = 1; 557 $this->_storeHeader($headerName, $this->_formatAddress($email, $name), true); 558 } 559 560 /** 561 * Adds To-header and recipient, $email can be an array, or a single string 562 * address 563 * 564 * @param string|array $email 565 * @param string $name 566 * @return Zend_Mail Provides fluent interface 567 */ 568 public function addTo($email, $name='') 569 { 570 if (!is_array($email)) { 571 $email = array($name => $email); 572 } 573 574 foreach ($email as $n => $recipient) { 575 $this->_addRecipientAndHeader('To', $recipient, is_int($n) ? '' : $n); 576 $this->_to[] = $recipient; 577 } 578 579 return $this; 580 } 581 582 /** 583 * Adds Cc-header and recipient, $email can be an array, or a single string 584 * address 585 * 586 * @param string|array $email 587 * @param string $name 588 * @return Zend_Mail Provides fluent interface 589 */ 590 public function addCc($email, $name='') 591 { 592 if (!is_array($email)) { 593 $email = array($name => $email); 594 } 595 596 foreach ($email as $n => $recipient) { 597 $this->_addRecipientAndHeader('Cc', $recipient, is_int($n) ? '' : $n); 598 } 599 600 return $this; 601 } 602 603 /** 604 * Adds Bcc recipient, $email can be an array, or a single string address 605 * 606 * @param string|array $email 607 * @return Zend_Mail Provides fluent interface 608 */ 609 public function addBcc($email) 610 { 611 if (!is_array($email)) { 612 $email = array($email); 613 } 614 615 foreach ($email as $recipient) { 616 $this->_addRecipientAndHeader('Bcc', $recipient, ''); 617 } 618 619 return $this; 620 } 621 622 /** 623 * Return list of recipient email addresses 624 * 625 * @return array (of strings) 626 */ 627 public function getRecipients() 628 { 629 return array_keys($this->_recipients); 630 } 631 632 /** 633 * Clear header from the message 634 * 635 * @param string $headerName 636 * @return Zend_Mail Provides fluent inter 637 */ 638 public function clearHeader($headerName) 639 { 640 if (isset($this->_headers[$headerName])){ 641 unset($this->_headers[$headerName]); 642 } 643 return $this; 644 } 645 646 /** 647 * Clears list of recipient email addresses 648 * 649 * @return Zend_Mail Provides fluent interface 650 */ 651 public function clearRecipients() 652 { 653 $this->_recipients = array(); 654 $this->_to = array(); 655 656 $this->clearHeader('To'); 657 $this->clearHeader('Cc'); 658 $this->clearHeader('Bcc'); 659 660 return $this; 661 } 662 663 /** 664 * Sets From-header and sender of the message 665 * 666 * @param string $email 667 * @param string $name 668 * @return Zend_Mail Provides fluent interface 669 * @throws Zend_Mail_Exception if called subsequent times 670 */ 671 public function setFrom($email, $name = null) 672 { 673 if (null !== $this->_from) { 674 /** 675 * @see Zend_Mail_Exception 676 */ 677 throw new Zend_Mail_Exception('From Header set twice'); 678 } 679 680 $email = $this->_filterEmail($email); 681 $name = $this->_filterName($name); 682 $this->_from = $email; 683 $this->_storeHeader('From', $this->_formatAddress($email, $name), true); 684 685 return $this; 686 } 687 688 /** 689 * Set Reply-To Header 690 * 691 * @param string $email 692 * @param string $name 693 * @return Zend_Mail 694 * @throws Zend_Mail_Exception if called more than one time 695 */ 696 public function setReplyTo($email, $name = null) 697 { 698 if (null !== $this->_replyTo) { 699 /** 700 * @see Zend_Mail_Exception 701 */ 702 throw new Zend_Mail_Exception('Reply-To Header set twice'); 703 } 704 705 $email = $this->_filterEmail($email); 706 $name = $this->_filterName($name); 707 $this->_replyTo = $email; 708 $this->_storeHeader('Reply-To', $this->_formatAddress($email, $name), true); 709 710 return $this; 711 } 712 713 /** 714 * Returns the sender of the mail 715 * 716 * @return string 717 */ 718 public function getFrom() 719 { 720 return $this->_from; 721 } 722 723 /** 724 * Returns the current Reply-To address of the message 725 * 726 * @return string|null Reply-To address, null when not set 727 */ 728 public function getReplyTo() 729 { 730 return $this->_replyTo; 731 } 732 733 /** 734 * Clears the sender from the mail 735 * 736 * @return Zend_Mail Provides fluent interface 737 */ 738 public function clearFrom() 739 { 740 $this->_from = null; 741 $this->clearHeader('From'); 742 743 return $this; 744 } 745 746 /** 747 * Clears the current Reply-To address from the message 748 * 749 * @return Zend_Mail Provides fluent interface 750 */ 751 public function clearReplyTo() 752 { 753 $this->_replyTo = null; 754 $this->clearHeader('Reply-To'); 755 756 return $this; 757 } 758 759 /** 760 * Sets Default From-email and name of the message 761 * 762 * @param string $email 763 * @param string $name optional 764 * @return void 765 */ 766 public static function setDefaultFrom($email, $name = null) 767 { 768 self::$_defaultFrom = array('email' => $email, 'name' => $name); 769 } 770 771 /** 772 * Returns the default sender of the mail 773 * 774 * @return null|array Null if none was set. 775 */ 776 public static function getDefaultFrom() 777 { 778 return self::$_defaultFrom; 779 } 780 781 /** 782 * Clears the default sender from the mail 783 * 784 * @return void 785 */ 786 public static function clearDefaultFrom() 787 { 788 self::$_defaultFrom = null; 789 } 790 791 /** 792 * Sets From-name and -email based on the defaults 793 * 794 * @return Zend_Mail Provides fluent interface 795 * @throws Zend_Mail_Exception 796 */ 797 public function setFromToDefaultFrom() { 798 $from = self::getDefaultFrom(); 799 if($from === null) { 800 throw new Zend_Mail_Exception( 801 'No default From Address set to use'); 802 } 803 804 $this->setFrom($from['email'], $from['name']); 805 806 return $this; 807 } 808 809 /** 810 * Sets Default ReplyTo-address and -name of the message 811 * 812 * @param string $email 813 * @param string $name optional 814 * @return void 815 */ 816 public static function setDefaultReplyTo($email, $name = null) 817 { 818 self::$_defaultReplyTo = array('email' => $email, 'name' => $name); 819 } 820 821 /** 822 * Returns the default Reply-To Address and Name of the mail 823 * 824 * @return null|array Null if none was set. 825 */ 826 public static function getDefaultReplyTo() 827 { 828 return self::$_defaultReplyTo; 829 } 830 831 /** 832 * Clears the default ReplyTo-address and -name from the mail 833 * 834 * @return void 835 */ 836 public static function clearDefaultReplyTo() 837 { 838 self::$_defaultReplyTo = null; 839 } 840 841 /** 842 * Sets ReplyTo-name and -email based on the defaults 843 * 844 * @return Zend_Mail Provides fluent interface 845 * @throws Zend_Mail_Exception 846 */ 847 public function setReplyToFromDefault() { 848 $replyTo = self::getDefaultReplyTo(); 849 if($replyTo === null) { 850 throw new Zend_Mail_Exception( 851 'No default Reply-To Address set to use'); 852 } 853 854 $this->setReplyTo($replyTo['email'], $replyTo['name']); 855 856 return $this; 857 } 858 859 /** 860 * Sets the Return-Path header of the message 861 * 862 * @param string $email 863 * @return Zend_Mail Provides fluent interface 864 * @throws Zend_Mail_Exception if set multiple times 865 */ 866 public function setReturnPath($email) 867 { 868 if ($this->_returnPath === null) { 869 $email = $this->_filterEmail($email); 870 $this->_returnPath = $email; 871 $this->_storeHeader('Return-Path', $email, false); 872 } else { 873 /** 874 * @see Zend_Mail_Exception 875 */ 876 throw new Zend_Mail_Exception('Return-Path Header set twice'); 877 } 878 return $this; 879 } 880 881 /** 882 * Returns the current Return-Path address of the message 883 * 884 * If no Return-Path header is set, returns the value of {@link $_from}. 885 * 886 * @return string 887 */ 888 public function getReturnPath() 889 { 890 if (null !== $this->_returnPath) { 891 return $this->_returnPath; 892 } 893 894 return $this->_from; 895 } 896 897 /** 898 * Clears the current Return-Path address from the message 899 * 900 * @return Zend_Mail Provides fluent interface 901 */ 902 public function clearReturnPath() 903 { 904 $this->_returnPath = null; 905 $this->clearHeader('Return-Path'); 906 907 return $this; 908 } 909 910 /** 911 * Sets the subject of the message 912 * 913 * @param string $subject 914 * @return Zend_Mail Provides fluent interface 915 * @throws Zend_Mail_Exception 916 */ 917 public function setSubject($subject) 918 { 919 if ($this->_subject === null) { 920 $subject = $this->_filterOther($subject); 921 $this->_subject = $this->_encodeHeader($subject); 922 $this->_storeHeader('Subject', $this->_subject); 923 } else { 924 /** 925 * @see Zend_Mail_Exception 926 */ 927 throw new Zend_Mail_Exception('Subject set twice'); 928 } 929 return $this; 930 } 931 932 /** 933 * Returns the encoded subject of the message 934 * 935 * @return string 936 */ 937 public function getSubject() 938 { 939 return $this->_subject; 940 } 941 942 /** 943 * Clears the encoded subject from the message 944 * 945 * @return Zend_Mail Provides fluent interface 946 */ 947 public function clearSubject() 948 { 949 $this->_subject = null; 950 $this->clearHeader('Subject'); 951 952 return $this; 953 } 954 955 /** 956 * Sets Date-header 957 * 958 * @param int|string|Zend_Date $date 959 * @return Zend_Mail Provides fluent interface 960 * @throws Zend_Mail_Exception if called subsequent times or wrong date 961 * format. 962 */ 963 public function setDate($date = null) 964 { 965 if ($this->_date === null) { 966 if ($date === null) { 967 $date = date('r'); 968 } else if (is_int($date)) { 969 $date = date('r', $date); 970 } else if (is_string($date)) { 971 $date = strtotime($date); 972 if ($date === false || $date < 0) { 973 /** 974 * @see Zend_Mail_Exception 975 */ 976 throw new Zend_Mail_Exception('String representations of Date Header must be ' . 977 'strtotime()-compatible'); 978 } 979 $date = date('r', $date); 980 } else if ($date instanceof Zend_Date) { 981 $date = $date->get(Zend_Date::RFC_2822); 982 } else { 983 /** 984 * @see Zend_Mail_Exception 985 */ 986 throw new Zend_Mail_Exception(__METHOD__ . ' only accepts UNIX timestamps, Zend_Date objects, ' . 987 ' and strtotime()-compatible strings'); 988 } 989 $this->_date = $date; 990 $this->_storeHeader('Date', $date); 991 } else { 992 /** 993 * @see Zend_Mail_Exception 994 */ 995 throw new Zend_Mail_Exception('Date Header set twice'); 996 } 997 return $this; 998 } 999 1000 /** 1001 * Returns the formatted date of the message 1002 * 1003 * @return string 1004 */ 1005 public function getDate() 1006 { 1007 return $this->_date; 1008 } 1009 1010 /** 1011 * Clears the formatted date from the message 1012 * 1013 * @return Zend_Mail Provides fluent interface 1014 */ 1015 public function clearDate() 1016 { 1017 $this->_date = null; 1018 $this->clearHeader('Date'); 1019 1020 return $this; 1021 } 1022 1023 /** 1024 * Sets the Message-ID of the message 1025 * 1026 * @param boolean|string $id 1027 * true :Auto 1028 * false :No set 1029 * null :No set 1030 * string:Sets given string (Angle brackets is not necessary) 1031 * @return Zend_Mail Provides fluent interface 1032 * @throws Zend_Mail_Exception 1033 */ 1034 public function setMessageId($id = true) 1035 { 1036 if ($id === null || $id === false) { 1037 return $this; 1038 } elseif ($id === true) { 1039 $id = $this->createMessageId(); 1040 } 1041 1042 if ($this->_messageId === null) { 1043 $id = $this->_filterOther($id); 1044 $this->_messageId = $id; 1045 $this->_storeHeader('Message-Id', '<' . $this->_messageId . '>'); 1046 } else { 1047 /** 1048 * @see Zend_Mail_Exception 1049 */ 1050 throw new Zend_Mail_Exception('Message-ID set twice'); 1051 } 1052 1053 return $this; 1054 } 1055 1056 /** 1057 * Returns the Message-ID of the message 1058 * 1059 * @return string 1060 */ 1061 public function getMessageId() 1062 { 1063 return $this->_messageId; 1064 } 1065 1066 1067 /** 1068 * Clears the Message-ID from the message 1069 * 1070 * @return Zend_Mail Provides fluent interface 1071 */ 1072 public function clearMessageId() 1073 { 1074 $this->_messageId = null; 1075 $this->clearHeader('Message-Id'); 1076 1077 return $this; 1078 } 1079 1080 /** 1081 * Creates the Message-ID 1082 * 1083 * @return string 1084 */ 1085 public function createMessageId() { 1086 1087 $time = time(); 1088 1089 if ($this->_from !== null) { 1090 $user = $this->_from; 1091 } elseif (isset($_SERVER['REMOTE_ADDR'])) { 1092 $user = $_SERVER['REMOTE_ADDR']; 1093 } else { 1094 $user = getmypid(); 1095 } 1096 1097 $rand = mt_rand(); 1098 1099 if ($this->_recipients !== array()) { 1100 $recipient = array_rand($this->_recipients); 1101 } else { 1102 $recipient = 'unknown'; 1103 } 1104 1105 if (isset($_SERVER["SERVER_NAME"])) { 1106 $hostName = $_SERVER["SERVER_NAME"]; 1107 } else { 1108 $hostName = php_uname('n'); 1109 } 1110 1111 return sha1($time . $user . $rand . $recipient) . '@' . $hostName; 1112 } 1113 1114 /** 1115 * Add a custom header to the message 1116 * 1117 * @param string $name 1118 * @param string $value 1119 * @param boolean $append 1120 * @return Zend_Mail Provides fluent interface 1121 * @throws Zend_Mail_Exception on attempts to create standard headers 1122 */ 1123 public function addHeader($name, $value, $append = false) 1124 { 1125 $prohibit = array('to', 'cc', 'bcc', 'from', 'subject', 1126 'reply-to', 'return-path', 1127 'date', 'message-id', 1128 ); 1129 if (in_array(strtolower($name), $prohibit)) { 1130 /** 1131 * @see Zend_Mail_Exception 1132 */ 1133 throw new Zend_Mail_Exception('Cannot set standard header from addHeader()'); 1134 } 1135 1136 $value = $this->_filterOther($value); 1137 $value = $this->_encodeHeader($value); 1138 $this->_storeHeader($name, $value, $append); 1139 1140 return $this; 1141 } 1142 1143 /** 1144 * Return mail headers 1145 * 1146 * @return array 1147 */ 1148 public function getHeaders() 1149 { 1150 return $this->_headers; 1151 } 1152 1153 /** 1154 * Sends this email using the given transport or a previously 1155 * set DefaultTransport or the internal mail function if no 1156 * default transport had been set. 1157 * 1158 * @param Zend_Mail_Transport_Abstract $transport 1159 * @return Zend_Mail Provides fluent interface 1160 */ 1161 public function send($transport = null) 1162 { 1163 if ($transport === null) { 1164 if (! self::$_defaultTransport instanceof Zend_Mail_Transport_Abstract) { 1165 $transport = new Zend_Mail_Transport_Sendmail(); 1166 } else { 1167 $transport = self::$_defaultTransport; 1168 } 1169 } 1170 1171 if ($this->_date === null) { 1172 $this->setDate(); 1173 } 1174 1175 if(null === $this->_from && null !== self::getDefaultFrom()) { 1176 $this->setFromToDefaultFrom(); 1177 } 1178 1179 if(null === $this->_replyTo && null !== self::getDefaultReplyTo()) { 1180 $this->setReplyToFromDefault(); 1181 } 1182 1183 $transport->send($this); 1184 1185 return $this; 1186 } 1187 1188 /** 1189 * Filter of email data 1190 * 1191 * @param string $email 1192 * @return string 1193 */ 1194 protected function _filterEmail($email) 1195 { 1196 $rule = array("\r" => '', 1197 "\n" => '', 1198 "\t" => '', 1199 '"' => '', 1200 ',' => '', 1201 '<' => '', 1202 '>' => '', 1203 ); 1204 1205 return strtr($email, $rule); 1206 } 1207 1208 /** 1209 * Filter of name data 1210 * 1211 * @param string $name 1212 * @return string 1213 */ 1214 protected function _filterName($name) 1215 { 1216 $rule = array("\r" => '', 1217 "\n" => '', 1218 "\t" => '', 1219 '"' => "'", 1220 '<' => '[', 1221 '>' => ']', 1222 ); 1223 1224 return trim(strtr($name, $rule)); 1225 } 1226 1227 /** 1228 * Filter of other data 1229 * 1230 * @param string $data 1231 * @return string 1232 */ 1233 protected function _filterOther($data) 1234 { 1235 $rule = array("\r" => '', 1236 "\n" => '', 1237 "\t" => '', 1238 ); 1239 1240 return strtr($data, $rule); 1241 } 1242 1243 /** 1244 * Formats e-mail address 1245 * 1246 * @param string $email 1247 * @param string $name 1248 * @return string 1249 */ 1250 protected function _formatAddress($email, $name) 1251 { 1252 if ($name === '' || $name === null || $name === $email) { 1253 return $email; 1254 } else { 1255 $encodedName = $this->_encodeHeader($name); 1256 if ($encodedName === $name && strcspn($name, '()<>[]:;@\\,.') != strlen($name)) { 1257 $format = '"%s" <%s>'; 1258 } else { 1259 $format = '%s <%s>'; 1260 } 1261 return sprintf($format, $encodedName, $email); 1262 } 1263 } 1264 1265} 1266