HeaderDecoder   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 82.86%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 0
dl 0
loc 74
ccs 29
cts 35
cp 0.8286
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C decode() 0 59 11
A convertCharset() 0 4 1
1
<?php
2
3
namespace Goetas\Mail\ToSwiftMailParser\Mime;
4
5
class HeaderDecoder
6
{
7
    private $decodeWindows1252;
8
9 10
    public function __construct(bool $decodeWindows1252 = false)
10
    {
11 10
        $this->decodeWindows1252 = $decodeWindows1252;
12 10
    }
13
14 10
    public function decode(string $string): string
15
    {
16
        /* Take out any spaces between multiple encoded words. */
17 10
        $string = preg_replace('|\?=\s+=\?|', '?==?', $string);
18
19 10
        $out = '';
20 10
        $old_pos = 0;
21
22 10
        while (($pos = strpos($string, '=?', $old_pos)) !== false) {
23
            /* Save any preceding text. */
24 6
            $out .= substr($string, $old_pos, $pos - $old_pos);
25
26
            /* Search for first delimiting question mark (charset). */
27 6
            if (($d1 = strpos($string, '?', $pos + 2)) === false) {
28
                break;
29
            }
30
31 6
            $orig_charset = substr($string, $pos + 2, $d1 - $pos - 2);
32 6
            if ($this->decodeWindows1252 && mb_strtolower($orig_charset) == 'iso-8859-1') {
33
                $orig_charset = 'windows-1252';
34
            }
35
36
            /* Search for second delimiting question mark (encoding). */
37 6
            if (($d2 = strpos($string, '?', $d1 + 1)) === false) {
38
                break;
39
            }
40
41 6
            $encoding = substr($string, $d1 + 1, $d2 - $d1 - 1);
42
43
            /* Search for end of encoded data. */
44 6
            if (($end = strpos($string, '?=', $d2 + 1)) === false) {
45
                break;
46
            }
47
48 6
            $encoded_text = substr($string, $d2 + 1, $end - $d2 - 1);
49
50
            switch ($encoding) {
51 6
                case 'Q':
52 5
                case 'q':
53 1
                    $out .= self::convertCharset(preg_replace_callback('/=([0-9a-f]{2})/i', function ($ord) {
54 1
                        return chr(hexdec($ord [1]));
55 1
                    }, str_replace('_', ' ', $encoded_text)), $orig_charset, mb_internal_encoding());
56 1
                    break;
57
58 5
                case 'B':
59
                case 'b':
60 5
                    $out .= self::convertCharset(base64_decode($encoded_text), $orig_charset, mb_internal_encoding());
61 5
                    break;
62
63
                default:
64
                    // Ignore unknown encoding.
65
                    break;
66
            }
67
68 6
            $old_pos = $end + 2;
69
        }
70
71 10
        return $out . substr($string, $old_pos);
72
    }
73
74 6
    private static function convertCharset(string $str, string $orig, string $to)
75
    {
76 6
        return mb_convert_encoding($str, $to, $orig);
77
    }
78
}
79