PageRenderTime 23ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/framework/vendor/swift/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php

http://zoop.googlecode.com/
PHP | 274 lines | 144 code | 27 blank | 103 comment | 15 complexity | 546829916217f50d005696795ccb9431 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1
  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. //@require 'Swift/Mime/Headers/UnstructuredHeader.php';
  10. //@require 'Swift/Mime/HeaderEncoder.php';
  11. //@require 'Swift/Mime/ParameterizedHeader.php';
  12. //@require 'Swift/Encoder.php';
  13. /**
  14. * An abstract base MIME Header.
  15. * @package Swift
  16. * @subpackage Mime
  17. * @author Chris Corbyn
  18. */
  19. class Swift_Mime_Headers_ParameterizedHeader
  20. extends Swift_Mime_Headers_UnstructuredHeader
  21. implements Swift_Mime_ParameterizedHeader
  22. {
  23. /**
  24. * The Encoder used to encode the parameters.
  25. * @var Swift_Encoder
  26. * @access private
  27. */
  28. private $_paramEncoder;
  29. /**
  30. * The parameters as an associative array.
  31. * @var string[]
  32. * @access private
  33. */
  34. private $_params = array();
  35. /**
  36. * RFC 2231's definition of a token.
  37. * @var string
  38. * @access private
  39. */
  40. private $_tokenRe;
  41. /**
  42. * Creates a new ParameterizedHeader with $name.
  43. * @param string $name
  44. * @param Swift_Mime_HeaderEncoder $encoder
  45. * @param Swift_Encoder $paramEncoder, optional
  46. */
  47. public function __construct($name, Swift_Mime_HeaderEncoder $encoder,
  48. Swift_Encoder $paramEncoder = null)
  49. {
  50. $this->setFieldName($name);
  51. $this->setEncoder($encoder);
  52. $this->_paramEncoder = $paramEncoder;
  53. $this->initializeGrammar();
  54. $this->_tokenRe = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)';
  55. }
  56. /**
  57. * Get the type of Header that this instance represents.
  58. * @return int
  59. * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX
  60. * @see TYPE_DATE, TYPE_ID, TYPE_PATH
  61. */
  62. public function getFieldType()
  63. {
  64. return self::TYPE_PARAMETERIZED;
  65. }
  66. /**
  67. * Set the character set used in this Header.
  68. * @param string $charset
  69. */
  70. public function setCharset($charset)
  71. {
  72. parent::setCharset($charset);
  73. if (isset($this->_paramEncoder))
  74. {
  75. $this->_paramEncoder->charsetChanged($charset);
  76. }
  77. }
  78. /**
  79. * Set the value of $parameter.
  80. * @param string $parameter
  81. * @param string $value
  82. */
  83. public function setParameter($parameter, $value)
  84. {
  85. $this->setParameters(array_merge($this->getParameters(), array($parameter => $value)));
  86. }
  87. /**
  88. * Get the value of $parameter.
  89. * @return string
  90. */
  91. public function getParameter($parameter)
  92. {
  93. $params = $this->getParameters();
  94. return array_key_exists($parameter, $params)
  95. ? $params[$parameter]
  96. : null;
  97. }
  98. /**
  99. * Set an associative array of parameter names mapped to values.
  100. * @param string[]
  101. */
  102. public function setParameters(array $parameters)
  103. {
  104. $this->clearCachedValueIf($this->_params != $parameters);
  105. $this->_params = $parameters;
  106. }
  107. /**
  108. * Returns an associative array of parameter names mapped to values.
  109. * @return string[]
  110. */
  111. public function getParameters()
  112. {
  113. return $this->_params;
  114. }
  115. /**
  116. * Get the value of this header prepared for rendering.
  117. * @return string
  118. */
  119. public function getFieldBody() //TODO: Check caching here
  120. {
  121. $body = parent::getFieldBody();
  122. foreach ($this->_params as $name => $value)
  123. {
  124. if (!is_null($value))
  125. {
  126. //Add the parameter
  127. $body .= '; ' . $this->_createParameter($name, $value);
  128. }
  129. }
  130. return $body;
  131. }
  132. // -- Protected methods
  133. /**
  134. * Generate a list of all tokens in the final header.
  135. * This doesn't need to be overridden in theory, but it is for implementation
  136. * reasons to prevent potential breakage of attributes.
  137. * @return string[]
  138. * @access protected
  139. */
  140. protected function toTokens($string = null)
  141. {
  142. $tokens = parent::toTokens(parent::getFieldBody());
  143. //Try creating any parameters
  144. foreach ($this->_params as $name => $value)
  145. {
  146. if (!is_null($value))
  147. {
  148. //Add the semi-colon separator
  149. $tokens[count($tokens)-1] .= ';';
  150. $tokens = array_merge($tokens, $this->generateTokenLines(
  151. ' ' . $this->_createParameter($name, $value)
  152. ));
  153. }
  154. }
  155. return $tokens;
  156. }
  157. // -- Private methods
  158. /**
  159. * Render a RFC 2047 compliant header parameter from the $name and $value.
  160. * @param string $name
  161. * @param string $value
  162. * @return string
  163. * @access private
  164. */
  165. private function _createParameter($name, $value)
  166. {
  167. $origValue = $value;
  168. $encoded = false;
  169. //Allow room for parameter name, indices, "=" and DQUOTEs
  170. $maxValueLength = $this->getMaxLineLength() - strlen($name . '=*N"";') - 1;
  171. $firstLineOffset = 0;
  172. //If it's not already a valid parameter value...
  173. if (!preg_match('/^' . $this->_tokenRe . '$/D', $value))
  174. {
  175. //TODO: text, or something else??
  176. //... and it's not ascii
  177. if (!preg_match('/^' . $this->getGrammar('text') . '*$/D', $value))
  178. {
  179. $encoded = true;
  180. //Allow space for the indices, charset and language
  181. $maxValueLength = $this->getMaxLineLength() - strlen($name . '*N*="";') - 1;
  182. $firstLineOffset = strlen(
  183. $this->getCharset() . "'" . $this->getLanguage() . "'"
  184. );
  185. }
  186. }
  187. //Encode if we need to
  188. if ($encoded || strlen($value) > $maxValueLength)
  189. {
  190. if (isset($this->_paramEncoder))
  191. {
  192. $value = $this->_paramEncoder->encodeString(
  193. $origValue, $firstLineOffset, $maxValueLength
  194. );
  195. }
  196. else //We have to go against RFC 2183/2231 in some areas for interoperability
  197. {
  198. $value = $this->getTokenAsEncodedWord($origValue);
  199. $encoded = false;
  200. }
  201. }
  202. $valueLines = isset($this->_paramEncoder) ? explode("\r\n", $value) : array($value);
  203. //Need to add indices
  204. if (count($valueLines) > 1)
  205. {
  206. $paramLines = array();
  207. foreach ($valueLines as $i => $line)
  208. {
  209. $paramLines[] = $name . '*' . $i .
  210. $this->_getEndOfParameterValue($line, $encoded, $i == 0);
  211. }
  212. return implode(";\r\n ", $paramLines);
  213. }
  214. else
  215. {
  216. return $name . $this->_getEndOfParameterValue(
  217. $valueLines[0], $encoded, true
  218. );
  219. }
  220. }
  221. /**
  222. * Returns the parameter value from the "=" and beyond.
  223. * @param string $value to append
  224. * @param boolean $encoded
  225. * @param boolean $firstLine
  226. * @return string
  227. * @access private
  228. */
  229. private function _getEndOfParameterValue($value, $encoded = false, $firstLine = false)
  230. {
  231. if (!preg_match('/^' . $this->_tokenRe . '$/D', $value))
  232. {
  233. $value = '"' . $value . '"';
  234. }
  235. $prepend = '=';
  236. if ($encoded)
  237. {
  238. $prepend = '*=';
  239. if ($firstLine)
  240. {
  241. $prepend = '*=' . $this->getCharset() . "'" . $this->getLanguage() .
  242. "'";
  243. }
  244. }
  245. return $prepend . $value;
  246. }
  247. }