Swift_Message_Headers   D
last analyzed

Complexity

Total Complexity 96

Size/Duplication

Total Lines 562
Duplicated Lines 3.74 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 21
loc 562
rs 4.8717
wmc 96
lcom 1
cbo 3

23 Methods

Rating   Name   Duplication   Size   Complexity  
A setLE() 0 10 3
A getLE() 0 4 1
A uncacheAll() 0 7 2
C set() 0 31 11
A get() 0 8 2
A remove() 0 11 3
A getList() 0 4 1
A has() 0 5 2
A setLanguage() 0 4 1
A getLanguage() 0 4 1
A setCharset() 0 4 1
A getCharset() 0 4 1
B setEncoding() 0 13 6
A getEncoding() 0 4 1
A forceEncoding() 0 4 1
B setAttribute() 0 20 6
A hasAttribute() 0 13 4
A getAttribute() 0 17 3
A removeAttribute() 0 9 2
A listAttributes() 0 9 2
F getEncoded() 21 110 26
C buildAttributes() 0 67 13
A build() 0 10 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Swift_Message_Headers often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Swift_Message_Headers, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Swift Mailer MIME Library Headers component
5
 * Please read the LICENSE file
6
 * @copyright Chris Corbyn <[email protected]>
7
 * @author Chris Corbyn <[email protected]>
8
 * @package Swift_Message
9
 * @license GNU Lesser General Public License
10
 */
11
12
require_once dirname(__FILE__) . "/../ClassLoader.php";
13
14
/**
15
 * Contains and constructs the headers for a MIME document
16
 * @package Swift_Message
17
 * @author Chris Corbyn <[email protected]>
18
 */
19
class Swift_Message_Headers
20
{
21
  /**
22
   * Headers which may contain email addresses, and therefore should take notice when encoding
23
   * @var array headers
24
   */
25
  protected $emailContainingHeaders = array(
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $emailContainingHeaders exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
26
    "To", "From", "Reply-To", "Cc", "Bcc", "Return-Path", "Sender");
27
  /**
28
   * The encoding format used for the body of the document
29
   * @var string format
30
   */
31
  protected $encoding = "B";
32
  /**
33
   * The charset used in the headers
34
   * @var string
35
   */
36
  protected $charset = false;
37
  /**
38
   * A collection of headers
39
   * @var array headers
40
   */
41
  protected $headers = array();
42
  /**
43
   * A container of references to the headers
44
   * @var array
45
   */
46
  protected $lowerHeaders = array();
47
  /**
48
   * Attributes appended to headers
49
   * @var array
50
   */
51
  protected $attributes = array();
52
  /**
53
   * If QP or Base64 encoding should be forced
54
   * @var boolean
55
   */
56
  protected $forceEncoding = false;
57
  /**
58
   * The language used in the headers (doesn't really matter much)
59
   * @var string
60
   */
61
  protected $language = "en-us";
62
  /**
63
   * Cached, pre-built headers
64
   * @var string
65
   */
66
  protected $cached = array();
67
  /**
68
   * The line ending used in the headers
69
   * @var string
70
   */
71
  protected $LE = "\r\n";
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $LE. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
72
  
73
  /**
74
   * Set the line ending character to use
75
   * @param string The line ending sequence
76
   * @return boolean
77
   */
78
  public function setLE($le)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $le. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
79
  {
80
    if (in_array($le, array("\r", "\n", "\r\n")))
81
    {
82
      foreach (array_keys($this->cached) as $k) $this->cached[$k] = null;
83
      $this->LE = $le;
84
      return true;
85
    }
86
    else return false;
87
  }
88
  /**
89
   * Get the line ending sequence
90
   * @return string
91
   */
92
  public function getLE()
93
  {
94
    return $this->LE;
95
  }
96
  /**
97
   * Reset the cache state in these headers
98
   */
99
  public function uncacheAll()
100
  {
101
    foreach (array_keys($this->cached) as $k)
102
    {
103
      $this->cached[$k] = null;
104
    }
105
  }
106
  /**
107
   * Add a header or change an existing header value
108
   * @param string The header name, for example "From" or "Subject"
109
   * @param string The value to be inserted into the header.  This is safe from header injection.
110
   */
111
  public function set($name, $value)
112
  {
113
    $lname = strtolower($name);
114
    if (!isset($this->lowerHeaders[$lname]))
115
    {
116
      $this->headers[$name] = null;
117
      $this->lowerHeaders[$lname] =& $this->headers[$name];
118
    }
119
    $this->cached[$lname] = null;
120
    Swift_ClassLoader::load("Swift_Message_Encoder");
121
    if (is_array($value))
122
    {
123
      foreach ($value as $v)
124
      {
125
        if (!$this->getCharset() && Swift_Message_Encoder::instance()->isUTF8($v))
126
        {
127
          $this->setCharset("utf-8");
128
          break;
129
        }
130
      }
131
    }
132
    elseif ($value !== null)
133
    {
134
      if (!$this->getCharset() && Swift_Message_Encoder::instance()->isUTF8($value))
135
      {
136
        $this->setCharset("utf-8");
137
      }
138
    }
139
    if (!is_array($value) && $value !== null) $this->lowerHeaders[$lname] = (string) $value;
140
    else $this->lowerHeaders[$lname] = $value;
141
  }
142
  /**
143
   * Get the value at a given header
144
   * @param string The name of the header, for example "From" or "Subject"
145
   * @return string
146
   * @throws Swift_Message_MimeException If no such header exists
147
   * @see hasHeader
148
   */
149
  public function get($name)
150
  {
151
    $lname = strtolower($name);
152
    if ($this->has($name))
153
    {
154
      return $this->lowerHeaders[$lname];
155
    }
156
  }
157
  /**
158
   * Remove a header from the list
159
   * @param string The name of the header
160
   */
161
  public function remove($name)
162
  {
163
    $lname = strtolower($name);
164
    if ($this->has($name))
165
    {
166
      unset($this->headers[$name]);
167
      unset($this->lowerHeaders[$lname]);
168
      unset($this->cached[$lname]);
169
      if (isset($this->attributes[$lname])) unset($this->attributes[$lname]);
170
    }
171
  }
172
  /**
173
   * Just fetch the array containing the headers
174
   * @return array
175
   */
176
  public function getList()
177
  {
178
    return $this->headers;
179
  }
180
  /**
181
   * Check if a header has been set or not
182
   * @param string The name of the header, for example "From" or "Subject"
183
   * @return boolean
184
   */
185
  public function has($name)
186
  {
187
    $lname = strtolower($name);
188
    return (array_key_exists($lname, $this->lowerHeaders) && $this->lowerHeaders[$lname] !== null);
189
  }
190
  /**
191
   * Set the language used in the headers to $lang (e.g. en-us, en-gb, sv etc)
192
   * @param string The language to use
193
   */
194
  public function setLanguage($lang)
195
  {
196
    $this->language = (string) $lang;
197
  }
198
  /**
199
   * Get the language used in the headers to $lang (e.g. en-us, en-gb, sv etc)
200
   * @return string
201
   */
202
  public function getLanguage()
203
  {
204
    return $this->language;
205
  }
206
  /**
207
   * Set the charset used in the headers
208
   * @param string The charset name
209
   * @param string $charset
210
   */
211
  public function setCharset($charset)
212
  {
213
    $this->charset = (string) $charset;
214
  }
215
  /**
216
   * Get the current charset used
217
   * @return string
218
   */
219
  public function getCharset()
220
  {
221
    return $this->charset;
222
  }
223
  /**
224
   * Specify the encoding to use for the headers if characters outside the 7-bit-printable ascii range are found
225
   * This encoding will never be used if only 7-bit-printable characters are found in the headers.
226
   * Possible values are:
227
   *  - QP
228
   *  - Q
229
   *  - Quoted-Printable
230
   *  - B
231
   *  - Base64
232
   * NOTE: Q, QP, Quoted-Printable are all the same; as are B and Base64
233
   * @param string The encoding format to use
234
   * @param string $encoding
235
   * @return boolean
236
   */
237
  public function setEncoding($encoding)
238
  {
239
    switch (strtolower($encoding))
240
    {
241
      case "qp": case "q": case "quoted-printable":
242
      $this->encoding = "Q";
243
      return true;
244
      case "base64": case "b":
245
      $this->encoding = "B";
246
      return true;
247
      default: return false;
248
    }
249
  }
250
  /**
251
   * Get the encoding format used in this document
252
   * @return string
253
   */
254
  public function getEncoding()
255
  {
256
    return $this->encoding;
257
  }
258
  /**
259
   * Turn on or off forced header encoding
260
   * @param boolean On/Off
261
   */
262
  public function forceEncoding($force=true)
263
  {
264
    $this->forceEncoding = (boolean) $force;
265
  }
266
  /**
267
   * Set an attribute in a major header
268
   * For example $headers->setAttribute("Content-Type", "format", "flowed")
269
   * @param string The main header these values exist in
270
   * @param string The name for this value
271
   * @param string The value to set
272
   * @throws Swift_Message_MimeException If no such header exists
273
   */
274
  public function setAttribute($header, $name, $value)
275
  {
276
    $name = strtolower($name);
277
    $lheader = strtolower($header);
278
    $this->cached[$lheader] = null;
279
    if (!$this->has($header))
280
    {
281
      throw new Swift_Message_MimeException(
282
      "Cannot set attribute '" . $name . "' for header '" . $header . "' as the header does not exist. " .
283
      "Consider using Swift_Message_Headers-&gt;has() to check.");
284
    }
285
    else
286
    {
287
      Swift_ClassLoader::load("Swift_Message_Encoder");
288
      if (!$this->getCharset() && Swift_Message_Encoder::instance()->isUTF8($value)) $this->setCharset("utf-8");
289
      if (!isset($this->attributes[$lheader])) $this->attributes[$lheader] = array();
290
      if ($value !== null) $this->attributes[$lheader][$name] = (string) $value;
291
      else $this->attributes[$lheader][$name] = $value;
292
    }
293
  }
294
  /**
295
   * Check if a header has a given attribute applied to it
296
   * @param string The name of the main header
297
   * @param string The name of the attribute
298
   * @param string $name
299
   * @return boolean
300
   */
301
  public function hasAttribute($header, $name)
302
  {
303
    $name = strtolower($name);
304
    $lheader = strtolower($header);
305
    if (!$this->has($header))
306
    {
307
      return false;
308
    }
309
    else
310
    {
311
      return (isset($this->attributes[$lheader]) && isset($this->attributes[$lheader][$name]) && ($this->attributes[$lheader][$name] !== null));
312
    }
313
  }
314
  /**
315
   * Get the value for a given attribute on a given header
316
   * @param string The name of the main header
317
   * @param string The name of the attribute
318
   * @param string $header
319
   * @param string $name
320
   * @return string
321
   * @throws Swift_Message_MimeException If no header is set
322
   */
323
  public function getAttribute($header, $name)
324
  {
325
    if (!$this->has($header))
326
    {
327
      throw new Swift_Message_MimeException(
328
      "Cannot locate attribute '" . $name . "' for header '" . $header . "' as the header does not exist. " .
329
      "Consider using Swift_Message_Headers-&gt;has() to check.");
330
    }
331
    
332
    $name = strtolower($name);
333
    $lheader = strtolower($header);
334
    
335
    if ($this->hasAttribute($header, $name))
336
    {
337
      return $this->attributes[$lheader][$name];
338
    }
339
  }
340
  /**
341
   * Remove an attribute from a header
342
   * @param string The name of the header to remove the attribute from
343
   * @param string The name of the attribute to remove
344
   */
345
  public function removeAttribute($header, $name)
346
  {
347
    $name = strtolower($name);
348
    $lheader = strtolower($header);
349
    if ($this->has($header))
350
    {
351
      unset($this->attributes[$lheader][$name]);
352
    }
353
  }
354
  /**
355
   * Get a list of all the attributes in the given header.
356
   * @param string The name of the header
357
   * @return array
358
   */
359
  public function listAttributes($header)
360
  {
361
    $header = strtolower($header);
362
    if (array_key_exists($header, $this->attributes))
363
    {
364
      return $this->attributes[$header];
365
    }
366
    else return array();
367
  }
368
  /**
369
   * Get the header in it's compliant, encoded form
370
   * @param string The name of the header
371
   * @return string
372
   * @throws Swift_Message_MimeException If the header doesn't exist
373
   */
374
  public function getEncoded($name)
375
  {
376
    if (!$this->getCharset()) $this->setCharset("iso-8859-1");
377
    Swift_ClassLoader::load("Swift_Message_Encoder");
378
    //I'll try as best I can to walk through this...
379
    
380
    $lname = strtolower($name);
381
    
382
    if ($this->cached[$lname] !== null) return $this->cached[$lname];
383
    
384
    $value = $this->get($name);
385
    
386
    $is_email = in_array($name, $this->emailContainingHeaders);
387
    
388
    $encoded_value = (array) $value; //Turn strings into arrays (just to make the following logic simpler)
389
    
390
    //Look at each value in this header
391
    // There will only be 1 value if it was a string to begin with, and usually only address lists will be multiple
392
    foreach ($encoded_value as $key => $row)
393
    {
394
      $spec = ""; //The bit which specifies the encoding of the header (if any)
395
      $end = ""; //The end delimiter for an encoded header
396
      
397
      //If the header is 7-bit printable it's at no risk of injection
398
      if (Swift_Message_Encoder::instance()->isHeaderSafe($row) && !$this->forceEncoding)
399
      {
400
        //Keeps the total line length at less than 76 chars, taking into account the Header name length
401
        $encoded_value[$key] = Swift_Message_Encoder::instance()->header7BitEncode(
402
          $row, 72, ($key > 0 ? 0 : (75-(strlen($name)+5))), $this->LE);
403
      }
404 View Code Duplication
      elseif ($this->encoding == "Q") //QP encode required
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
405
      {
406
        $spec = "=?" . $this->getCharset() . "?Q?"; //e.g. =?iso-8859-1?Q?
407
        $end = "?=";
408
        //Calculate the length of, for example: "From: =?iso-8859-1?Q??="
409
        $used_length = strlen($name) + 2 + strlen($spec) + 2;
410
        
411
        //Encode to QP, excluding the specification for now but keeping the lines short enough to be compliant
412
        $encoded_value[$key] = str_replace(" ", "_", Swift_Message_Encoder::instance()->QPEncode(
413
          $row, (75-(strlen($spec)+6)), ($key > 0 ? 0 : (75-$used_length)), true, $this->LE));
414
        
415
      }
416 View Code Duplication
      elseif ($this->encoding == "B") //Need to Base64 encode
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
417
      {
418
        //See the comments in the elseif() above since the logic is the same (refactor?)
419
        $spec = "=?" . $this->getCharset() . "?B?";
420
        $end = "?=";
421
        $used_length = strlen($name) + 2 + strlen($spec) + 2;
422
        $encoded_value[$key] = Swift_Message_Encoder::instance()->base64Encode(
423
          $row, (75-(strlen($spec)+5)), ($key > 0 ? 0 : (76-($used_length+3))), true, $this->LE);
424
      }
425
      
426
      if (false !== $p = strpos($encoded_value[$key], $this->LE))
427
      {
428
        $cb = 'str_replace("' . $this->LE . '", "", "<$1>");';
429
        $encoded_value[$key] = preg_replace("/<([^>]+)>/e", $cb, $encoded_value[$key]);
430
      }
431
      
432
      //Turn our header into an array of lines ready for wrapping around the encoding specification
433
      $lines = explode($this->LE, $encoded_value[$key]);
434
      
435
      for ($i = 0, $len = count($lines); $i < $len; $i++)
436
      {
437
        //Don't allow commas in address fields without quotes unless they're encoded
438
        if (empty($spec) && $is_email && (false !== $p = strpos($lines[$i], ",")))
439
        {
440
          $s = strpos($lines[$i], " <");
441
          $e = strpos($lines[$i], ">");
442
          if ($s < $e)
443
          {
444
            $addr = substr($lines[$i], $s);
445
            $lines[$i] = "\"" . substr($lines[$i], 0, $s) . "\"" . $addr;
446
          }
447
          else
448
          {
449
            $lines[$i] = "\"" . $lines[$i] . "\"";
450
          }
451
        }
452
        
453
        if ($this->encoding == "Q") $lines[$i] = rtrim($lines[$i], "=");
454
        
455
        if ($lines[$i] == "" && $i > 0)
456
        {
457
          unset($lines[$i]); //Empty line, we'd rather not have these in the headers thank you!
458
          continue;
459
        }
460
        if ($i > 0)
461
        {
462
          //Don't stick the specification part around the line if it's an address
463
          if (substr($lines[$i], 0, 1) == '<' && substr($lines[$i], -1) == '>') $lines[$i] = " " . $lines[$i];
464
          else $lines[$i] = " " . $spec . $lines[$i] . $end;
465
        }
466
        else
467
        {
468
          if (substr($lines[$i], 0, 1) != '<' || substr($lines[$i], -1) != '>') $lines[$i] = $spec . $lines[$i] . $end;
469
        }
470
      }
471
      //Build back into a string, now includes the specification
472
      $encoded_value[$key] = implode($this->LE, $lines);
473
      $lines = null;
0 ignored issues
show
Unused Code introduced by
$lines is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
474
    }
475
    
476
    //If there are multiple values in this header, put them on separate lines, cleared by commas
477
    $this->cached[$lname] = implode("," . $this->LE . " ", $encoded_value);
478
    
479
    //Append attributes if there are any
480
    if (!empty($this->attributes[$lname])) $this->cached[$lname] .= $this->buildAttributes($this->cached[$lname], $lname);
481
    
482
    return $this->cached[$lname];
483
  }
484
  /**
485
   * Build the list of attributes for appending to the given header
486
   * This is RFC 2231 & 2047 compliant.
487
   * A HUGE thanks to Joaquim Homrighausen for heaps of help, advice
488
   * and testing to get this working rock solid.
489
   * @param string The header built without attributes
490
   * @param string The lowercase name of the header
491
   * @param string $header_line
492
   * @param string $header_name
493
   * @return string
494
   * @throws Swift_Message_MimeException If no such header exists or there are no attributes
495
   */
496
  protected function buildAttributes($header_line, $header_name)
497
  {
498
    Swift_ClassLoader::load("Swift_Message_Encoder");
499
    $lines = explode($this->LE, $header_line);
500
    $used_len = strlen($lines[count($lines)-1]);
501
    $lines= null;
0 ignored issues
show
Unused Code introduced by
$lines is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
502
    $ret = "";
503
    foreach ($this->attributes[$header_name] as $attribute => $att_value)
504
    {
505
      if ($att_value === null) continue;
506
      // 70 to account for LWSP, CRLF, quotes and a semi-colon
507
      // + length of attribute
508
      // + 4 for a 2 digit number and 2 asterisks
509
      $avail_len = 70 - (strlen($attribute) + 4);
510
      $encoded = Swift_Message_Encoder::instance()->rfc2047Encode($att_value, $this->charset, $this->language, $avail_len, $this->LE);
511
      $lines = explode($this->LE, $encoded);
512
      foreach ($lines as $i => $line)
513
      {
514
        //Add quotes if needed (RFC 2045)
515
        if (preg_match("~[\\s\";,<>\\(\\)@:\\\\/\\[\\]\\?=]~", $line)) $lines[$i] = '"' . $line . '"';
516
      }
517
      $encoded = implode($this->LE, $lines);
518
      
519
      //If we can fit this entire attribute onto the same line as the header then do it!
520
      if ((strlen($encoded) + $used_len + strlen($attribute) + 4) < 74)
521
      {
522
        if (strpos($encoded, "'") !== false) $attribute .= "*";
523
        $append = "; " . $attribute . "=" . $encoded;
524
        $ret .= $append;
525
        $used_len += strlen($append);
526
      }
527
      else //... otherwise list of underneath
528
      {
529
        $ret .= ";";
530
        if (count($lines) > 1)
531
        {
532
          $loop = false;
533
          $add_asterisk = false;
534
          foreach ($lines as $i => $line)
535
          {
536
            $att_copy = $attribute; //Because it's multi-line it needs asterisks with decimal indices
537
            $att_copy .= "*" . $i;
538
            if ($add_asterisk || strpos($encoded, "'") !== false)
539
            {
540
              $att_copy .= "*"; //And if it's got a ' then it needs another asterisk
541
              $add_asterisk = true;
542
            }
543
            $append = "";
544
            if ($loop) $append .= ";";
545
            $append .= $this->LE . " " . $att_copy . "=" . $line;
546
            $ret .= $append;
547
            $used_len = strlen($append)+1;
548
            $loop = true;
549
          }
550
        }
551
        else
552
        {
553
          if (strpos($encoded, "'") !== false) $attribute .= "*";
554
          $append = $this->LE . " " . $attribute . "=" . $encoded;
555
          $used_len = strlen($append)+1;
556
          $ret .= $append;
557
        }
558
      }
559
      $lines= null;
0 ignored issues
show
Unused Code introduced by
$lines is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
560
    }
561
    return $ret;
562
  }
563
  /**
564
   * Compile the list of headers which have been set and return an ascii string
565
   * The return value should always be 7-bit ascii and will have been cleaned for header injection
566
   * If this looks complicated it's probably because it is!!  Keeping everything compliant is not easy.
567
   * This is RFC 2822 compliant
568
   * @return string
569
   */
570
  public function build()
571
  {
572
    $ret = "";
573
    foreach ($this->headers as $name => $value) //Look at each header
574
    {
575
      if ($value === null) continue;
576
      $ret .= ltrim($name, ".") . ": " . $this->getEncoded($name) . $this->LE;
577
    }
578
    return trim($ret);
579
  }
580
}
581