SimpleHeaderSet.php 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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 collection of MIME headers.
  11. *
  12. * @package Swift
  13. * @subpackage Mime
  14. * @author Chris Corbyn
  15. */
  16. class Swift_Mime_SimpleHeaderSet implements Swift_Mime_HeaderSet
  17. {
  18. /** HeaderFactory */
  19. private $_factory;
  20. /** Collection of set Headers */
  21. private $_headers = array();
  22. /** Field ordering details */
  23. private $_order = array();
  24. /** List of fields which are required to be displayed */
  25. private $_required = array();
  26. /** The charset used by Headers */
  27. private $_charset;
  28. /**
  29. * Create a new SimpleHeaderSet with the given $factory.
  30. *
  31. * @param Swift_Mime_HeaderFactory $factory
  32. * @param string $charset
  33. */
  34. public function __construct(Swift_Mime_HeaderFactory $factory, $charset = null)
  35. {
  36. $this->_factory = $factory;
  37. if (isset($charset)) {
  38. $this->setCharset($charset);
  39. }
  40. }
  41. /**
  42. * Set the charset used by these headers.
  43. *
  44. * @param string $charset
  45. */
  46. public function setCharset($charset)
  47. {
  48. $this->_charset = $charset;
  49. $this->_factory->charsetChanged($charset);
  50. $this->_notifyHeadersOfCharset($charset);
  51. }
  52. /**
  53. * Add a new Mailbox Header with a list of $addresses.
  54. *
  55. * @param string $name
  56. * @param array|string $addresses
  57. */
  58. public function addMailboxHeader($name, $addresses = null)
  59. {
  60. $this->_storeHeader($name,
  61. $this->_factory->createMailboxHeader($name, $addresses));
  62. }
  63. /**
  64. * Add a new Date header using $timestamp (UNIX time).
  65. *
  66. * @param string $name
  67. * @param integer $timestamp
  68. */
  69. public function addDateHeader($name, $timestamp = null)
  70. {
  71. $this->_storeHeader($name,
  72. $this->_factory->createDateHeader($name, $timestamp));
  73. }
  74. /**
  75. * Add a new basic text header with $name and $value.
  76. *
  77. * @param string $name
  78. * @param string $value
  79. */
  80. public function addTextHeader($name, $value = null)
  81. {
  82. $this->_storeHeader($name,
  83. $this->_factory->createTextHeader($name, $value));
  84. }
  85. /**
  86. * Add a new ParameterizedHeader with $name, $value and $params.
  87. *
  88. * @param string $name
  89. * @param string $value
  90. * @param array $params
  91. */
  92. public function addParameterizedHeader($name, $value = null, $params = array())
  93. {
  94. $this->_storeHeader($name,
  95. $this->_factory->createParameterizedHeader($name, $value,
  96. $params));
  97. }
  98. /**
  99. * Add a new ID header for Message-ID or Content-ID.
  100. *
  101. * @param string $name
  102. * @param string|array $ids
  103. */
  104. public function addIdHeader($name, $ids = null)
  105. {
  106. $this->_storeHeader($name, $this->_factory->createIdHeader($name, $ids));
  107. }
  108. /**
  109. * Add a new Path header with an address (path) in it.
  110. *
  111. * @param string $name
  112. * @param string $path
  113. */
  114. public function addPathHeader($name, $path = null)
  115. {
  116. $this->_storeHeader($name, $this->_factory->createPathHeader($name, $path));
  117. }
  118. /**
  119. * Returns true if at least one header with the given $name exists.
  120. *
  121. * If multiple headers match, the actual one may be specified by $index.
  122. *
  123. * @param string $name
  124. * @param integer $index
  125. *
  126. * @return boolean
  127. */
  128. public function has($name, $index = 0)
  129. {
  130. $lowerName = strtolower($name);
  131. return array_key_exists($lowerName, $this->_headers)
  132. && array_key_exists($index, $this->_headers[$lowerName]);
  133. }
  134. /**
  135. * Set a header in the HeaderSet.
  136. *
  137. * The header may be a previously fetched header via {@link get()} or it may
  138. * be one that has been created separately.
  139. *
  140. * If $index is specified, the header will be inserted into the set at this
  141. * offset.
  142. *
  143. * @param Swift_Mime_Header $header
  144. * @param integer $index
  145. */
  146. public function set(Swift_Mime_Header $header, $index = 0)
  147. {
  148. $this->_storeHeader($header->getFieldName(), $header, $index);
  149. }
  150. /**
  151. * Get the header with the given $name.
  152. *
  153. * If multiple headers match, the actual one may be specified by $index.
  154. * Returns NULL if none present.
  155. *
  156. * @param string $name
  157. * @param integer $index
  158. *
  159. * @return Swift_Mime_Header
  160. */
  161. public function get($name, $index = 0)
  162. {
  163. if ($this->has($name, $index)) {
  164. $lowerName = strtolower($name);
  165. return $this->_headers[$lowerName][$index];
  166. }
  167. }
  168. /**
  169. * Get all headers with the given $name.
  170. *
  171. * @param string $name
  172. *
  173. * @return array
  174. */
  175. public function getAll($name = null)
  176. {
  177. if (!isset($name)) {
  178. $headers = array();
  179. foreach ($this->_headers as $collection) {
  180. $headers = array_merge($headers, $collection);
  181. }
  182. return $headers;
  183. }
  184. $lowerName = strtolower($name);
  185. if (!array_key_exists($lowerName, $this->_headers)) {
  186. return array();
  187. }
  188. return $this->_headers[$lowerName];
  189. }
  190. /**
  191. * Remove the header with the given $name if it's set.
  192. *
  193. * If multiple headers match, the actual one may be specified by $index.
  194. *
  195. * @param string $name
  196. * @param integer $index
  197. */
  198. public function remove($name, $index = 0)
  199. {
  200. $lowerName = strtolower($name);
  201. unset($this->_headers[$lowerName][$index]);
  202. }
  203. /**
  204. * Remove all headers with the given $name.
  205. *
  206. * @param string $name
  207. */
  208. public function removeAll($name)
  209. {
  210. $lowerName = strtolower($name);
  211. unset($this->_headers[$lowerName]);
  212. }
  213. /**
  214. * Create a new instance of this HeaderSet.
  215. *
  216. * @return Swift_Mime_HeaderSet
  217. */
  218. public function newInstance()
  219. {
  220. return new self($this->_factory);
  221. }
  222. /**
  223. * Define a list of Header names as an array in the correct order.
  224. *
  225. * These Headers will be output in the given order where present.
  226. *
  227. * @param array $sequence
  228. */
  229. public function defineOrdering(array $sequence)
  230. {
  231. $this->_order = array_flip(array_map('strtolower', $sequence));
  232. }
  233. /**
  234. * Set a list of header names which must always be displayed when set.
  235. *
  236. * Usually headers without a field value won't be output unless set here.
  237. *
  238. * @param array $names
  239. */
  240. public function setAlwaysDisplayed(array $names)
  241. {
  242. $this->_required = array_flip(array_map('strtolower', $names));
  243. }
  244. /**
  245. * Notify this observer that the entity's charset has changed.
  246. *
  247. * @param string $charset
  248. */
  249. public function charsetChanged($charset)
  250. {
  251. $this->setCharset($charset);
  252. }
  253. /**
  254. * Returns a string with a representation of all headers.
  255. *
  256. * @return string
  257. */
  258. public function toString()
  259. {
  260. $string = '';
  261. $headers = $this->_headers;
  262. if ($this->_canSort()) {
  263. uksort($headers, array($this, '_sortHeaders'));
  264. }
  265. foreach ($headers as $collection) {
  266. foreach ($collection as $header) {
  267. if ($this->_isDisplayed($header) || $header->getFieldBody() != '') {
  268. $string .= $header->toString();
  269. }
  270. }
  271. }
  272. return $string;
  273. }
  274. /**
  275. * Returns a string representation of this object.
  276. *
  277. * @return string
  278. *
  279. * @see toString()
  280. */
  281. public function __toString()
  282. {
  283. return $this->toString();
  284. }
  285. // -- Private methods
  286. /** Save a Header to the internal collection */
  287. private function _storeHeader($name, Swift_Mime_Header $header, $offset = null)
  288. {
  289. if (!isset($this->_headers[strtolower($name)])) {
  290. $this->_headers[strtolower($name)] = array();
  291. }
  292. if (!isset($offset)) {
  293. $this->_headers[strtolower($name)][] = $header;
  294. } else {
  295. $this->_headers[strtolower($name)][$offset] = $header;
  296. }
  297. }
  298. /** Test if the headers can be sorted */
  299. private function _canSort()
  300. {
  301. return count($this->_order) > 0;
  302. }
  303. /** uksort() algorithm for Header ordering */
  304. private function _sortHeaders($a, $b)
  305. {
  306. $lowerA = strtolower($a);
  307. $lowerB = strtolower($b);
  308. $aPos = array_key_exists($lowerA, $this->_order)
  309. ? $this->_order[$lowerA]
  310. : -1;
  311. $bPos = array_key_exists($lowerB, $this->_order)
  312. ? $this->_order[$lowerB]
  313. : -1;
  314. if ($aPos == -1) {
  315. return 1;
  316. } elseif ($bPos == -1) {
  317. return -1;
  318. }
  319. return ($aPos < $bPos) ? -1 : 1;
  320. }
  321. /** Test if the given Header is always displayed */
  322. private function _isDisplayed(Swift_Mime_Header $header)
  323. {
  324. return array_key_exists(strtolower($header->getFieldName()), $this->_required);
  325. }
  326. /** Notify all Headers of the new charset */
  327. private function _notifyHeadersOfCharset($charset)
  328. {
  329. foreach ($this->_headers as $headerGroup) {
  330. foreach ($headerGroup as $header) {
  331. $header->setCharset($charset);
  332. }
  333. }
  334. }
  335. }