|
TYPO3 API
SVNRelease
|
00001 <?php 00002 00003 /* 00004 * This file is part of SwiftMailer. 00005 * (c) 2004-2009 Chris Corbyn 00006 * 00007 * For the full copyright and license information, please view the LICENSE 00008 * file that was distributed with this source code. 00009 */ 00010 00011 //@require 'Swift/Mime/Headers/UnstructuredHeader.php'; 00012 //@require 'Swift/Mime/HeaderEncoder.php'; 00013 //@require 'Swift/Mime/ParameterizedHeader.php'; 00014 //@require 'Swift/Encoder.php'; 00015 00016 /** 00017 * An abstract base MIME Header. 00018 * @package Swift 00019 * @subpackage Mime 00020 * @author Chris Corbyn 00021 */ 00022 class Swift_Mime_Headers_ParameterizedHeader 00023 extends Swift_Mime_Headers_UnstructuredHeader 00024 implements Swift_Mime_ParameterizedHeader 00025 { 00026 00027 /** 00028 * The Encoder used to encode the parameters. 00029 * @var Swift_Encoder 00030 * @access private 00031 */ 00032 private $_paramEncoder; 00033 00034 /** 00035 * The parameters as an associative array. 00036 * @var string[] 00037 * @access private 00038 */ 00039 private $_params = array(); 00040 00041 /** 00042 * RFC 2231's definition of a token. 00043 * @var string 00044 * @access private 00045 */ 00046 private $_tokenRe; 00047 00048 /** 00049 * Creates a new ParameterizedHeader with $name. 00050 * @param string $name 00051 * @param Swift_Mime_HeaderEncoder $encoder 00052 * @param Swift_Encoder $paramEncoder, optional 00053 */ 00054 public function __construct($name, Swift_Mime_HeaderEncoder $encoder, 00055 Swift_Encoder $paramEncoder = null) 00056 { 00057 $this->setFieldName($name); 00058 $this->setEncoder($encoder); 00059 $this->_paramEncoder = $paramEncoder; 00060 $this->initializeGrammar(); 00061 $this->_tokenRe = '(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)'; 00062 } 00063 00064 /** 00065 * Get the type of Header that this instance represents. 00066 * @return int 00067 * @see TYPE_TEXT, TYPE_PARAMETERIZED, TYPE_MAILBOX 00068 * @see TYPE_DATE, TYPE_ID, TYPE_PATH 00069 */ 00070 public function getFieldType() 00071 { 00072 return self::TYPE_PARAMETERIZED; 00073 } 00074 00075 /** 00076 * Set the character set used in this Header. 00077 * @param string $charset 00078 */ 00079 public function setCharset($charset) 00080 { 00081 parent::setCharset($charset); 00082 if (isset($this->_paramEncoder)) 00083 { 00084 $this->_paramEncoder->charsetChanged($charset); 00085 } 00086 } 00087 00088 /** 00089 * Set the value of $parameter. 00090 * @param string $parameter 00091 * @param string $value 00092 */ 00093 public function setParameter($parameter, $value) 00094 { 00095 $this->setParameters(array_merge($this->getParameters(), array($parameter => $value))); 00096 } 00097 00098 /** 00099 * Get the value of $parameter. 00100 * @return string 00101 */ 00102 public function getParameter($parameter) 00103 { 00104 $params = $this->getParameters(); 00105 return array_key_exists($parameter, $params) 00106 ? $params[$parameter] 00107 : null; 00108 } 00109 00110 /** 00111 * Set an associative array of parameter names mapped to values. 00112 * @param string[] 00113 */ 00114 public function setParameters(array $parameters) 00115 { 00116 $this->clearCachedValueIf($this->_params != $parameters); 00117 $this->_params = $parameters; 00118 } 00119 00120 /** 00121 * Returns an associative array of parameter names mapped to values. 00122 * @return string[] 00123 */ 00124 public function getParameters() 00125 { 00126 return $this->_params; 00127 } 00128 00129 /** 00130 * Get the value of this header prepared for rendering. 00131 * @return string 00132 */ 00133 public function getFieldBody() //TODO: Check caching here 00134 { 00135 $body = parent::getFieldBody(); 00136 foreach ($this->_params as $name => $value) 00137 { 00138 if (!is_null($value)) 00139 { 00140 //Add the parameter 00141 $body .= '; ' . $this->_createParameter($name, $value); 00142 } 00143 } 00144 return $body; 00145 } 00146 00147 // -- Protected methods 00148 00149 /** 00150 * Generate a list of all tokens in the final header. 00151 * This doesn't need to be overridden in theory, but it is for implementation 00152 * reasons to prevent potential breakage of attributes. 00153 * @return string[] 00154 * @access protected 00155 */ 00156 protected function toTokens($string = null) 00157 { 00158 $tokens = parent::toTokens(parent::getFieldBody()); 00159 00160 //Try creating any parameters 00161 foreach ($this->_params as $name => $value) 00162 { 00163 if (!is_null($value)) 00164 { 00165 //Add the semi-colon separator 00166 $tokens[count($tokens)-1] .= ';'; 00167 $tokens = array_merge($tokens, $this->generateTokenLines( 00168 ' ' . $this->_createParameter($name, $value) 00169 )); 00170 } 00171 } 00172 00173 return $tokens; 00174 } 00175 00176 // -- Private methods 00177 00178 /** 00179 * Render a RFC 2047 compliant header parameter from the $name and $value. 00180 * @param string $name 00181 * @param string $value 00182 * @return string 00183 * @access private 00184 */ 00185 private function _createParameter($name, $value) 00186 { 00187 $origValue = $value; 00188 00189 $encoded = false; 00190 //Allow room for parameter name, indices, "=" and DQUOTEs 00191 $maxValueLength = $this->getMaxLineLength() - strlen($name . '=*N"";') - 1; 00192 $firstLineOffset = 0; 00193 00194 //If it's not already a valid parameter value... 00195 if (!preg_match('/^' . $this->_tokenRe . '$/D', $value)) 00196 { 00197 //TODO: text, or something else?? 00198 //... and it's not ascii 00199 if (!preg_match('/^' . $this->getGrammar('text') . '*$/D', $value)) 00200 { 00201 $encoded = true; 00202 //Allow space for the indices, charset and language 00203 $maxValueLength = $this->getMaxLineLength() - strlen($name . '*N*="";') - 1; 00204 $firstLineOffset = strlen( 00205 $this->getCharset() . "'" . $this->getLanguage() . "'" 00206 ); 00207 } 00208 } 00209 00210 //Encode if we need to 00211 if ($encoded || strlen($value) > $maxValueLength) 00212 { 00213 if (isset($this->_paramEncoder)) 00214 { 00215 $value = $this->_paramEncoder->encodeString( 00216 $origValue, $firstLineOffset, $maxValueLength 00217 ); 00218 } 00219 else //We have to go against RFC 2183/2231 in some areas for interoperability 00220 { 00221 $value = $this->getTokenAsEncodedWord($origValue); 00222 $encoded = false; 00223 } 00224 } 00225 00226 $valueLines = isset($this->_paramEncoder) ? explode("\r\n", $value) : array($value); 00227 00228 //Need to add indices 00229 if (count($valueLines) > 1) 00230 { 00231 $paramLines = array(); 00232 foreach ($valueLines as $i => $line) 00233 { 00234 $paramLines[] = $name . '*' . $i . 00235 $this->_getEndOfParameterValue($line, $encoded, $i == 0); 00236 } 00237 return implode(";\r\n ", $paramLines); 00238 } 00239 else 00240 { 00241 return $name . $this->_getEndOfParameterValue( 00242 $valueLines[0], $encoded, true 00243 ); 00244 } 00245 } 00246 00247 /** 00248 * Returns the parameter value from the "=" and beyond. 00249 * @param string $value to append 00250 * @param boolean $encoded 00251 * @param boolean $firstLine 00252 * @return string 00253 * @access private 00254 */ 00255 private function _getEndOfParameterValue($value, $encoded = false, $firstLine = false) 00256 { 00257 if (!preg_match('/^' . $this->_tokenRe . '$/D', $value)) 00258 { 00259 $value = '"' . $value . '"'; 00260 } 00261 $prepend = '='; 00262 if ($encoded) 00263 { 00264 $prepend = '*='; 00265 if ($firstLine) 00266 { 00267 $prepend = '*=' . $this->getCharset() . "'" . $this->getLanguage() . 00268 "'"; 00269 } 00270 } 00271 return $prepend . $value; 00272 } 00273 00274 }
1.8.0