PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/apps/libraries/swift_mailer/classes/Swift/Mime/Headers/ParameterizedHeader.php

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