Mail.php 31 KB

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