Passed
Push — 1.0.0 ( fcaf32...d3c3e6 )
by Zaahid
03:21
created

SplitParameterToken::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * This file is part of the ZBateson\MailMimeParser project.
4
 *
5
 * @license http://opensource.org/licenses/bsd-license.php BSD
6
 */
7
namespace ZBateson\MailMimeParser\Header\Part;
8
9
use ZBateson\MailMimeParser\Util\CharsetConverter;
10
11
/**
12
 * Holds a running value for an RFC-2231 split header parameter.
13
 * 
14
 * ParameterConsumer creates SplitParameterTokens when a split header parameter
15
 * is first found, and adds subsequent split parts to an already created one if
16
 * the parameter name matches.
17
 *
18
 * @author Zaahid Bateson
19
 */
20
class SplitParameterToken extends HeaderPart
21
{
22
    /**
23
     * @var string name of the parameter.
24
     */
25
    protected $name;
26
27
    /**
28
     * @var string[] keeps encoded parts values that need to be decoded.  Keys
29
     *      are set to the index part of the split parameter and used for
30
     *      sorting before decoding/concatenating.
31
     */
32
    protected $encodedParts = [];
33
34
    /**
35
     * @var string contains literal parts that don't require any decoding (and
36
     *      are therefore ISO-8859-1 (technically should be 7bit US-ASCII but
37
     *      allowing 8bit shouldn't be an issue as elsewhere in MMP).
38
     */
39
    protected $literalParts = [];
40
41
    /**
42
     * @var string RFC-1766 (or subset) language code with optional subtags,
43
     *      regions, etc...
44
     */
45
    protected $language;
46
47
    /**
48
     * @var string charset of content in $encodedParts.
49
     */
50
    protected $charset = 'ISO-8859-1';
51
52
    /**
53
     * Initializes a SplitParameterToken.
54
     * 
55
     * @param CharsetConverter $charsetConverter
56
     * @param string $name the parameter's name
57
     */
58 13
    public function __construct(CharsetConverter $charsetConverter, $name)
59
    {
60 13
        parent::__construct($charsetConverter, '');
0 ignored issues
show
Unused Code introduced by
The call to HeaderPart::__construct() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
61 13
        $this->name = trim($name);
62 13
    }
63
64
    /**
65
     * Extracts charset and language from an encoded value, setting them on the
66
     * current object if $index is 0 and adds the value part to the encodedParts
67
     * array.
68
     * 
69
     * @param string $value
70
     * @param int $index
71
     */
72 9
    protected function extractMetaInformationAndValue($value, $index)
73
    {
74 9
        if (preg_match('~^([^\']*)\'([^\']*)\'(.*)$~', $value, $matches)) {
75 6
            if ($index === 0) {
76 6
                $this->charset = (!empty($matches[1])) ? $matches[1] : $this->charset;
77 6
                $this->language = (!empty($matches[2])) ? $matches[2] : $this->language;
78 6
            }
79 6
            $value = $matches[3];
80 6
        }
81 9
        $this->encodedParts[$index] = $value;
82 9
    }
83
    
84
    /**
85
     * Adds the passed part to the running array of values.
86
     * 
87
     * If $isEncoded is true, language and charset info is extracted from the
88
     * value, and the value is decoded before returning in getValue.
89
     * 
90
     * The value of the parameter is sorted based on the passed $index
91
     * arguments when adding before concatenating when re-constructing the
92
     * value.
93
     * 
94
     * @param string $value
95
     * @param boolean $isEncoded
96
     * @param int $index
97
     */
98 12
    public function addPart($value, $isEncoded, $index)
99
    {
100 12
        if (empty($index)) {
101 12
            $index = 0;
102 12
        }
103 12
        if ($isEncoded) {
104 9
            $this->extractMetaInformationAndValue($value, $index);
105 9
        } else {
106 5
            $this->literalParts[$index] = $this->convertEncoding($value);
107
        }
108 12
    }
109
    
110
    /**
111
     * Traverses $this->encodedParts until a non-sequential key is found, or the
112
     * end of the array is found.
113
     * 
114
     * This allows encoded parts of a split parameter to be split anywhere and
115
     * reconstructed.
116
     * 
117
     * The returned string is converted to UTF-8 before being returned.
118
     * 
119
     * @return string
120
     */
121 7
    private function getNextEncodedValue()
122
    {
123 7
        $cur = current($this->encodedParts);
124 7
        $key = key($this->encodedParts);
125 7
        $running = '';
126 7
        while ($cur !== false) {
127 7
            $running .= $cur;
128 7
            $cur = next($this->encodedParts);
129 7
            $nKey = key($this->encodedParts);
130 7
            if ($nKey !== $key + 1) {
131 7
                break;
132
            }
133 6
            $key = $nKey;
134 6
        }
135 7
        return $this->convertEncoding(
136 7
            rawurldecode($running),
137 7
            $this->charset,
138
            true
139 7
        );
140
    }
141
    
142
    /**
143
     * Reconstructs the value of the split parameter into a single UTF-8 string
144
     * and returns it.
145
     * 
146
     * @return string
147
     */
148 10
    public function getValue()
149
    {
150 10
        $parts = $this->literalParts;
151
        
152 10
        reset($this->encodedParts);
153 10
        ksort($this->encodedParts);
154 10
        while (current($this->encodedParts) !== false) {
155 7
            $parts[key($this->encodedParts)] = $this->getNextEncodedValue();
156 7
        }
157
        
158 10
        ksort($parts);
159 10
        return array_reduce(
160 10
            $parts,
161 10
            function ($carry, $item) {
162 10
                return $carry . $item;
163 10
            },
164
            ''
165 10
        );
166
    }
167
    
168
    /**
169
     * Returns the name of the parameter.
170
     * 
171
     * @return string
172
     */
173 1
    public function getName()
174
    {
175 1
        return $this->name;
176
    }
177
    
178
    /**
179
     * Returns the language of the parameter if set, or null if not.
180
     * 
181
     * @return string
182
     */
183 5
    public function getLanguage()
184
    {
185 5
        return $this->language;
186
    }
187
}
188