SimpleMessage.php 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. <?php
  2. /*
  3. * This file is part of SwiftMailer.
  4. * (c) 2004-2009 Chris Corbyn
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * The default email message class.
  11. * @package Swift
  12. * @subpackage Mime
  13. * @author Chris Corbyn
  14. */
  15. class Swift_Mime_SimpleMessage extends Swift_Mime_MimePart
  16. implements Swift_Mime_Message
  17. {
  18. /**
  19. * Create a new SimpleMessage with $headers, $encoder and $cache.
  20. * @param Swift_Mime_HeaderSet $headers
  21. * @param Swift_Mime_ContentEncoder $encoder
  22. * @param Swift_KeyCache $cache
  23. * @param Swift_Mime_Grammar $grammar
  24. * @param string $charset
  25. */
  26. public function __construct(Swift_Mime_HeaderSet $headers,
  27. Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar, $charset = null)
  28. {
  29. parent::__construct($headers, $encoder, $cache, $grammar, $charset);
  30. $this->getHeaders()->defineOrdering(array(
  31. 'Return-Path',
  32. 'Sender',
  33. 'Message-ID',
  34. 'Date',
  35. 'Subject',
  36. 'From',
  37. 'Reply-To',
  38. 'To',
  39. 'Cc',
  40. 'Bcc',
  41. 'MIME-Version',
  42. 'Content-Type',
  43. 'Content-Transfer-Encoding'
  44. ));
  45. $this->getHeaders()->setAlwaysDisplayed(
  46. array('Date', 'Message-ID', 'From')
  47. );
  48. $this->getHeaders()->addTextHeader('MIME-Version', '1.0');
  49. $this->setDate(time());
  50. $this->setId($this->getId());
  51. $this->getHeaders()->addMailboxHeader('From');
  52. }
  53. /**
  54. * Always returns {@link LEVEL_TOP} for a message instance.
  55. * @return int
  56. */
  57. public function getNestingLevel()
  58. {
  59. return self::LEVEL_TOP;
  60. }
  61. /**
  62. * Set the subject of this message.
  63. * @param string $subject
  64. */
  65. public function setSubject($subject)
  66. {
  67. if (!$this->_setHeaderFieldModel('Subject', $subject))
  68. {
  69. $this->getHeaders()->addTextHeader('Subject', $subject);
  70. }
  71. return $this;
  72. }
  73. /**
  74. * Get the subject of this message.
  75. * @return string
  76. */
  77. public function getSubject()
  78. {
  79. return $this->_getHeaderFieldModel('Subject');
  80. }
  81. /**
  82. * Set the date at which this message was created.
  83. * @param int $date
  84. */
  85. public function setDate($date)
  86. {
  87. if (!$this->_setHeaderFieldModel('Date', $date))
  88. {
  89. $this->getHeaders()->addDateHeader('Date', $date);
  90. }
  91. return $this;
  92. }
  93. /**
  94. * Get the date at which this message was created.
  95. * @return int
  96. */
  97. public function getDate()
  98. {
  99. return $this->_getHeaderFieldModel('Date');
  100. }
  101. /**
  102. * Set the return-path (the bounce address) of this message.
  103. * @param string $address
  104. */
  105. public function setReturnPath($address)
  106. {
  107. if (!$this->_setHeaderFieldModel('Return-Path', $address))
  108. {
  109. $this->getHeaders()->addPathHeader('Return-Path', $address);
  110. }
  111. return $this;
  112. }
  113. /**
  114. * Get the return-path (bounce address) of this message.
  115. * @return string
  116. */
  117. public function getReturnPath()
  118. {
  119. return $this->_getHeaderFieldModel('Return-Path');
  120. }
  121. /**
  122. * Set the sender of this message.
  123. * This does not override the From field, but it has a higher significance.
  124. * @param string $sender
  125. * @param string $name optional
  126. */
  127. public function setSender($address, $name = null)
  128. {
  129. if (!is_array($address) && isset($name))
  130. {
  131. $address = array($address => $name);
  132. }
  133. if (!$this->_setHeaderFieldModel('Sender', (array) $address))
  134. {
  135. $this->getHeaders()->addMailboxHeader('Sender', (array) $address);
  136. }
  137. return $this;
  138. }
  139. /**
  140. * Get the sender of this message.
  141. * @return string
  142. */
  143. public function getSender()
  144. {
  145. return $this->_getHeaderFieldModel('Sender');
  146. }
  147. /**
  148. * Add a From: address to this message.
  149. *
  150. * If $name is passed this name will be associated with the address.
  151. *
  152. * @param string $address
  153. * @param string $name optional
  154. */
  155. public function addFrom($address, $name = null)
  156. {
  157. $current = $this->getFrom();
  158. $current[$address] = $name;
  159. return $this->setFrom($current);
  160. }
  161. /**
  162. * Set the from address of this message.
  163. *
  164. * You may pass an array of addresses if this message is from multiple people.
  165. *
  166. * If $name is passed and the first parameter is a string, this name will be
  167. * associated with the address.
  168. *
  169. * @param string $addresses
  170. * @param string $name optional
  171. */
  172. public function setFrom($addresses, $name = null)
  173. {
  174. if (!is_array($addresses) && isset($name))
  175. {
  176. $addresses = array($addresses => $name);
  177. }
  178. if (!$this->_setHeaderFieldModel('From', (array) $addresses))
  179. {
  180. $this->getHeaders()->addMailboxHeader('From', (array) $addresses);
  181. }
  182. return $this;
  183. }
  184. /**
  185. * Get the from address of this message.
  186. *
  187. * @return string
  188. */
  189. public function getFrom()
  190. {
  191. return $this->_getHeaderFieldModel('From');
  192. }
  193. /**
  194. * Add a Reply-To: address to this message.
  195. *
  196. * If $name is passed this name will be associated with the address.
  197. *
  198. * @param string $address
  199. * @param string $name optional
  200. */
  201. public function addReplyTo($address, $name = null)
  202. {
  203. $current = $this->getReplyTo();
  204. $current[$address] = $name;
  205. return $this->setReplyTo($current);
  206. }
  207. /**
  208. * Set the reply-to address of this message.
  209. *
  210. * You may pass an array of addresses if replies will go to multiple people.
  211. *
  212. * If $name is passed and the first parameter is a string, this name will be
  213. * associated with the address.
  214. *
  215. * @param string $addresses
  216. * @param string $name optional
  217. */
  218. public function setReplyTo($addresses, $name = null)
  219. {
  220. if (!is_array($addresses) && isset($name))
  221. {
  222. $addresses = array($addresses => $name);
  223. }
  224. if (!$this->_setHeaderFieldModel('Reply-To', (array) $addresses))
  225. {
  226. $this->getHeaders()->addMailboxHeader('Reply-To', (array) $addresses);
  227. }
  228. return $this;
  229. }
  230. /**
  231. * Get the reply-to address of this message.
  232. *
  233. * @return string
  234. */
  235. public function getReplyTo()
  236. {
  237. return $this->_getHeaderFieldModel('Reply-To');
  238. }
  239. /**
  240. * Add a To: address to this message.
  241. *
  242. * If $name is passed this name will be associated with the address.
  243. *
  244. * @param string $address
  245. * @param string $name optional
  246. */
  247. public function addTo($address, $name = null)
  248. {
  249. $current = $this->getTo();
  250. $current[$address] = $name;
  251. return $this->setTo($current);
  252. }
  253. /**
  254. * Set the to addresses of this message.
  255. *
  256. * If multiple recipients will receive the message and array should be used.
  257. *
  258. * If $name is passed and the first parameter is a string, this name will be
  259. * associated with the address.
  260. *
  261. * @param array $addresses
  262. * @param string $name optional
  263. */
  264. public function setTo($addresses, $name = null)
  265. {
  266. if (!is_array($addresses) && isset($name))
  267. {
  268. $addresses = array($addresses => $name);
  269. }
  270. if (!$this->_setHeaderFieldModel('To', (array) $addresses))
  271. {
  272. $this->getHeaders()->addMailboxHeader('To', (array) $addresses);
  273. }
  274. return $this;
  275. }
  276. /**
  277. * Get the To addresses of this message.
  278. *
  279. * @return array
  280. */
  281. public function getTo()
  282. {
  283. return $this->_getHeaderFieldModel('To');
  284. }
  285. /**
  286. * Add a Cc: address to this message.
  287. *
  288. * If $name is passed this name will be associated with the address.
  289. *
  290. * @param string $address
  291. * @param string $name optional
  292. */
  293. public function addCc($address, $name = null)
  294. {
  295. $current = $this->getCc();
  296. $current[$address] = $name;
  297. return $this->setCc($current);
  298. }
  299. /**
  300. * Set the Cc addresses of this message.
  301. *
  302. * If $name is passed and the first parameter is a string, this name will be
  303. * associated with the address.
  304. *
  305. * @param array $addresses
  306. * @param string $name optional
  307. */
  308. public function setCc($addresses, $name = null)
  309. {
  310. if (!is_array($addresses) && isset($name))
  311. {
  312. $addresses = array($addresses => $name);
  313. }
  314. if (!$this->_setHeaderFieldModel('Cc', (array) $addresses))
  315. {
  316. $this->getHeaders()->addMailboxHeader('Cc', (array) $addresses);
  317. }
  318. return $this;
  319. }
  320. /**
  321. * Get the Cc address of this message.
  322. *
  323. * @return array
  324. */
  325. public function getCc()
  326. {
  327. return $this->_getHeaderFieldModel('Cc');
  328. }
  329. /**
  330. * Add a Bcc: address to this message.
  331. *
  332. * If $name is passed this name will be associated with the address.
  333. *
  334. * @param string $address
  335. * @param string $name optional
  336. */
  337. public function addBcc($address, $name = null)
  338. {
  339. $current = $this->getBcc();
  340. $current[$address] = $name;
  341. return $this->setBcc($current);
  342. }
  343. /**
  344. * Set the Bcc addresses of this message.
  345. *
  346. * If $name is passed and the first parameter is a string, this name will be
  347. * associated with the address.
  348. *
  349. * @param array $addresses
  350. * @param string $name optional
  351. */
  352. public function setBcc($addresses, $name = null)
  353. {
  354. if (!is_array($addresses) && isset($name))
  355. {
  356. $addresses = array($addresses => $name);
  357. }
  358. if (!$this->_setHeaderFieldModel('Bcc', (array) $addresses))
  359. {
  360. $this->getHeaders()->addMailboxHeader('Bcc', (array) $addresses);
  361. }
  362. return $this;
  363. }
  364. /**
  365. * Get the Bcc addresses of this message.
  366. *
  367. * @return array
  368. */
  369. public function getBcc()
  370. {
  371. return $this->_getHeaderFieldModel('Bcc');
  372. }
  373. /**
  374. * Set the priority of this message.
  375. * The value is an integer where 1 is the highest priority and 5 is the lowest.
  376. * @param int $priority
  377. */
  378. public function setPriority($priority)
  379. {
  380. $priorityMap = array(
  381. 1 => 'Highest',
  382. 2 => 'High',
  383. 3 => 'Normal',
  384. 4 => 'Low',
  385. 5 => 'Lowest'
  386. );
  387. $pMapKeys = array_keys($priorityMap);
  388. if ($priority > max($pMapKeys))
  389. {
  390. $priority = max($pMapKeys);
  391. }
  392. elseif ($priority < min($pMapKeys))
  393. {
  394. $priority = min($pMapKeys);
  395. }
  396. if (!$this->_setHeaderFieldModel('X-Priority',
  397. sprintf('%d (%s)', $priority, $priorityMap[$priority])))
  398. {
  399. $this->getHeaders()->addTextHeader('X-Priority',
  400. sprintf('%d (%s)', $priority, $priorityMap[$priority]));
  401. }
  402. return $this;
  403. }
  404. /**
  405. * Get the priority of this message.
  406. * The returned value is an integer where 1 is the highest priority and 5
  407. * is the lowest.
  408. * @return int
  409. */
  410. public function getPriority()
  411. {
  412. list($priority) = sscanf($this->_getHeaderFieldModel('X-Priority'),
  413. '%[1-5]'
  414. );
  415. return isset($priority) ? $priority : 3;
  416. }
  417. /**
  418. * Ask for a delivery receipt from the recipient to be sent to $addresses
  419. * @param array $addresses
  420. */
  421. public function setReadReceiptTo($addresses)
  422. {
  423. if (!$this->_setHeaderFieldModel('Disposition-Notification-To', $addresses))
  424. {
  425. $this->getHeaders()
  426. ->addMailboxHeader('Disposition-Notification-To', $addresses);
  427. }
  428. return $this;
  429. }
  430. /**
  431. * Get the addresses to which a read-receipt will be sent.
  432. * @return string
  433. */
  434. public function getReadReceiptTo()
  435. {
  436. return $this->_getHeaderFieldModel('Disposition-Notification-To');
  437. }
  438. /**
  439. * Attach a {@link Swift_Mime_MimeEntity} such as an Attachment or MimePart.
  440. * @param Swift_Mime_MimeEntity $entity
  441. */
  442. public function attach(Swift_Mime_MimeEntity $entity)
  443. {
  444. $this->setChildren(array_merge($this->getChildren(), array($entity)));
  445. return $this;
  446. }
  447. /**
  448. * Remove an already attached entity.
  449. * @param Swift_Mime_MimeEntity $entity
  450. */
  451. public function detach(Swift_Mime_MimeEntity $entity)
  452. {
  453. $newChildren = array();
  454. foreach ($this->getChildren() as $child)
  455. {
  456. if ($entity !== $child)
  457. {
  458. $newChildren[] = $child;
  459. }
  460. }
  461. $this->setChildren($newChildren);
  462. return $this;
  463. }
  464. /**
  465. * Attach a {@link Swift_Mime_MimeEntity} and return it's CID source.
  466. * This method should be used when embedding images or other data in a message.
  467. * @param Swift_Mime_MimeEntity $entity
  468. * @return string
  469. */
  470. public function embed(Swift_Mime_MimeEntity $entity)
  471. {
  472. $this->attach($entity);
  473. return 'cid:' . $entity->getId();
  474. }
  475. /**
  476. * Get this message as a complete string.
  477. * @return string
  478. */
  479. public function toString()
  480. {
  481. if (count($children = $this->getChildren()) > 0 && $this->getBody() != '')
  482. {
  483. $this->setChildren(array_merge(array($this->_becomeMimePart()), $children));
  484. $string = parent::toString();
  485. $this->setChildren($children);
  486. }
  487. else
  488. {
  489. $string = parent::toString();
  490. }
  491. return $string;
  492. }
  493. /**
  494. * Returns a string representation of this object.
  495. *
  496. * @return string
  497. *
  498. * @see toString()
  499. */
  500. public function __toString()
  501. {
  502. return $this->toString();
  503. }
  504. /**
  505. * Write this message to a {@link Swift_InputByteStream}.
  506. * @param Swift_InputByteStream $is
  507. */
  508. public function toByteStream(Swift_InputByteStream $is)
  509. {
  510. if (count($children = $this->getChildren()) > 0 && $this->getBody() != '')
  511. {
  512. $this->setChildren(array_merge(array($this->_becomeMimePart()), $children));
  513. parent::toByteStream($is);
  514. $this->setChildren($children);
  515. }
  516. else
  517. {
  518. parent::toByteStream($is);
  519. }
  520. }
  521. // -- Protected methods
  522. /** @see Swift_Mime_SimpleMimeEntity::_getIdField() */
  523. protected function _getIdField()
  524. {
  525. return 'Message-ID';
  526. }
  527. // -- Private methods
  528. /** Turn the body of this message into a child of itself if needed */
  529. private function _becomeMimePart()
  530. {
  531. $part = new parent($this->getHeaders()->newInstance(), $this->getEncoder(),
  532. $this->_getCache(), $this->_getGrammar(), $this->_userCharset
  533. );
  534. $part->setContentType($this->_userContentType);
  535. $part->setBody($this->getBody());
  536. $part->setFormat($this->_userFormat);
  537. $part->setDelSp($this->_userDelSp);
  538. $part->_setNestingLevel($this->_getTopNestingLevel());
  539. return $part;
  540. }
  541. /** Get the highest nesting level nested inside this message */
  542. private function _getTopNestingLevel()
  543. {
  544. $highestLevel = $this->getNestingLevel();
  545. foreach ($this->getChildren() as $child)
  546. {
  547. $childLevel = $child->getNestingLevel();
  548. if ($highestLevel < $childLevel)
  549. {
  550. $highestLevel = $childLevel;
  551. }
  552. }
  553. return $highestLevel;
  554. }
  555. }