Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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
 */
22
class 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
}