MailboxHeader.php 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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. * A Mailbox Address MIME Header for something like From or Sender.
  11. * @package Swift
  12. * @subpackage Mime
  13. * @author Chris Corbyn
  14. */
  15. class Swift_Mime_Headers_MailboxHeader extends Swift_Mime_Headers_AbstractHeader
  16. {
  17. /**
  18. * The mailboxes used in this Header.
  19. * @var string[]
  20. * @access private
  21. */
  22. private $_mailboxes = array();
  23. /**
  24. * Creates a new MailboxHeader with $name.
  25. * @param string $name of Header
  26. * @param Swift_Mime_HeaderEncoder $encoder
  27. * @param Swift_Mime_Grammar $grammar
  28. */
  29. public function __construct($name, Swift_Mime_HeaderEncoder $encoder, Swift_Mime_Grammar $grammar)
  30. {
  31. $this->setFieldName($name);
  32. $this->setEncoder($encoder);
  33. parent::__construct($grammar);
  34. }
  35. /**
  36. * Get the type of Header that this instance represents.
  37. * @return int
  38. * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
  39. * @see TYPE_DATE, TYPE_ID, TYPE_PATH
  40. */
  41. public function getFieldType()
  42. {
  43. return self::TYPE_MAILBOX;
  44. }
  45. /**
  46. * Set the model for the field body.
  47. * This method takes a string, or an array of addresses.
  48. * @param mixed $model
  49. * @throws Swift_RfcComplianceException
  50. */
  51. public function setFieldBodyModel($model)
  52. {
  53. $this->setNameAddresses($model);
  54. }
  55. /**
  56. * Get the model for the field body.
  57. * This method returns an associative array like {@link getNameAddresses()}
  58. * @return array
  59. * @throws Swift_RfcComplianceException
  60. */
  61. public function getFieldBodyModel()
  62. {
  63. return $this->getNameAddresses();
  64. }
  65. /**
  66. * Set a list of mailboxes to be shown in this Header.
  67. * The mailboxes can be a simple array of addresses, or an array of
  68. * key=>value pairs where (email => personalName).
  69. * Example:
  70. * <code>
  71. * <?php
  72. * //Sets two mailboxes in the Header, one with a personal name
  73. * $header->setNameAddresses(array(
  74. * 'chris@swiftmailer.org' => 'Chris Corbyn',
  75. * 'mark@swiftmailer.org' //No associated personal name
  76. * ));
  77. * ?>
  78. * </code>
  79. * @param string|string[] $mailboxes
  80. * @throws Swift_RfcComplianceException
  81. * @see __construct()
  82. * @see setAddresses()
  83. * @see setValue()
  84. */
  85. public function setNameAddresses($mailboxes)
  86. {
  87. $this->_mailboxes = $this->normalizeMailboxes((array) $mailboxes);
  88. $this->setCachedValue(null); //Clear any cached value
  89. }
  90. /**
  91. * Get the full mailbox list of this Header as an array of valid RFC 2822 strings.
  92. * Example:
  93. * <code>
  94. * <?php
  95. * $header = new Swift_Mime_Headers_MailboxHeader('From',
  96. * array('chris@swiftmailer.org' => 'Chris Corbyn',
  97. * 'mark@swiftmailer.org' => 'Mark Corbyn')
  98. * );
  99. * print_r($header->getNameAddressStrings());
  100. * // array (
  101. * // 0 => Chris Corbyn <chris@swiftmailer.org>,
  102. * // 1 => Mark Corbyn <mark@swiftmailer.org>
  103. * // )
  104. * ?>
  105. * </code>
  106. * @return string[]
  107. * @throws Swift_RfcComplianceException
  108. * @see getNameAddresses()
  109. * @see toString()
  110. */
  111. public function getNameAddressStrings()
  112. {
  113. return $this->_createNameAddressStrings($this->getNameAddresses());
  114. }
  115. /**
  116. * Get all mailboxes in this Header as key=>value pairs.
  117. * The key is the address and the value is the name (or null if none set).
  118. * Example:
  119. * <code>
  120. * <?php
  121. * $header = new Swift_Mime_Headers_MailboxHeader('From',
  122. * array('chris@swiftmailer.org' => 'Chris Corbyn',
  123. * 'mark@swiftmailer.org' => 'Mark Corbyn')
  124. * );
  125. * print_r($header->getNameAddresses());
  126. * // array (
  127. * // chris@swiftmailer.org => Chris Corbyn,
  128. * // mark@swiftmailer.org => Mark Corbyn
  129. * // )
  130. * ?>
  131. * </code>
  132. * @return string[]
  133. * @see getAddresses()
  134. * @see getNameAddressStrings()
  135. */
  136. public function getNameAddresses()
  137. {
  138. return $this->_mailboxes;
  139. }
  140. /**
  141. * Makes this Header represent a list of plain email addresses with no names.
  142. * Example:
  143. * <code>
  144. * <?php
  145. * //Sets three email addresses as the Header data
  146. * $header->setAddresses(
  147. * array('one@domain.tld', 'two@domain.tld', 'three@domain.tld')
  148. * );
  149. * ?>
  150. * </code>
  151. * @param string[] $addresses
  152. * @throws Swift_RfcComplianceException
  153. * @see setNameAddresses()
  154. * @see setValue()
  155. */
  156. public function setAddresses($addresses)
  157. {
  158. $this->setNameAddresses(array_values((array) $addresses));
  159. }
  160. /**
  161. * Get all email addresses in this Header.
  162. * @return string[]
  163. * @see getNameAddresses()
  164. */
  165. public function getAddresses()
  166. {
  167. return array_keys($this->_mailboxes);
  168. }
  169. /**
  170. * Remove one or more addresses from this Header.
  171. * @param string|string[] $addresses
  172. */
  173. public function removeAddresses($addresses)
  174. {
  175. $this->setCachedValue(null);
  176. foreach ((array) $addresses as $address) {
  177. unset($this->_mailboxes[$address]);
  178. }
  179. }
  180. /**
  181. * Get the string value of the body in this Header.
  182. * This is not necessarily RFC 2822 compliant since folding white space will
  183. * not be added at this stage (see {@link toString()} for that).
  184. * @return string
  185. * @throws Swift_RfcComplianceException
  186. * @see toString()
  187. */
  188. public function getFieldBody()
  189. {
  190. //Compute the string value of the header only if needed
  191. if (is_null($this->getCachedValue())) {
  192. $this->setCachedValue($this->createMailboxListString($this->_mailboxes));
  193. }
  194. return $this->getCachedValue();
  195. }
  196. // -- Points of extension
  197. /**
  198. * Normalizes a user-input list of mailboxes into consistent key=>value pairs.
  199. * @param string[] $mailboxes
  200. * @return string[]
  201. * @access protected
  202. */
  203. protected function normalizeMailboxes(array $mailboxes)
  204. {
  205. $actualMailboxes = array();
  206. foreach ($mailboxes as $key => $value) {
  207. if (is_string($key)) { //key is email addr
  208. $address = $key;
  209. $name = $value;
  210. } else {
  211. $address = $value;
  212. $name = null;
  213. }
  214. $this->_assertValidAddress($address);
  215. $actualMailboxes[$address] = $name;
  216. }
  217. return $actualMailboxes;
  218. }
  219. /**
  220. * Produces a compliant, formatted display-name based on the string given.
  221. * @param string $displayName as displayed
  222. * @param boolean $shorten the first line to make remove for header name
  223. * @return string
  224. * @access protected
  225. */
  226. protected function createDisplayNameString($displayName, $shorten = false)
  227. {
  228. return $this->createPhrase($this, $displayName,
  229. $this->getCharset(), $this->getEncoder(), $shorten
  230. );
  231. }
  232. /**
  233. * Creates a string form of all the mailboxes in the passed array.
  234. * @param string[] $mailboxes
  235. * @return string
  236. * @throws Swift_RfcComplianceException
  237. * @access protected
  238. */
  239. protected function createMailboxListString(array $mailboxes)
  240. {
  241. return implode(', ', $this->_createNameAddressStrings($mailboxes));
  242. }
  243. /**
  244. * Redefine the encoding requirements for mailboxes. Commas and semicolons are used to separate
  245. * multiple addresses, and should therefore be encoded
  246. * @param string $token
  247. * @return boolean
  248. */
  249. protected function tokenNeedsEncoding($token)
  250. {
  251. return preg_match('/[,;]/', $token) || parent::tokenNeedsEncoding($token);
  252. }
  253. // -- Private methods
  254. /**
  255. * Return an array of strings conforming the the name-addr spec of RFC 2822.
  256. * @param string[] $mailboxes
  257. * @return string[]
  258. * @access private
  259. */
  260. private function _createNameAddressStrings(array $mailboxes)
  261. {
  262. $strings = array();
  263. foreach ($mailboxes as $email => $name) {
  264. $mailboxStr = $email;
  265. if (!is_null($name)) {
  266. $nameStr = $this->createDisplayNameString($name, empty($strings));
  267. $mailboxStr = $nameStr . ' <' . $mailboxStr . '>';
  268. }
  269. $strings[] = $mailboxStr;
  270. }
  271. return $strings;
  272. }
  273. /**
  274. * Throws an Exception if the address passed does not comply with RFC 2822.
  275. * @param string $address
  276. * @throws Swift_RfcComplianceException If invalid.
  277. * @access private
  278. */
  279. private function _assertValidAddress($address)
  280. {
  281. if (!preg_match('/^' . $this->getGrammar()->getDefinition('addr-spec') . '$/D',
  282. $address))
  283. {
  284. throw new Swift_RfcComplianceException(
  285. 'Address in mailbox given [' . $address .
  286. '] does not comply with RFC 2822, 3.6.2.'
  287. );
  288. }
  289. }
  290. }