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