Passed
Push — 1.0.0 ( 5c7ec9...fcaf32 )
by Zaahid
03:19
created

SplitParameterToken::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 0
cts 4
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 2
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
    public function __construct(CharsetConverter $charsetConverter, $name)
59
    {
60
        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
        $this->name = trim($name);
62
    }
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
    protected function extractMetaInformationAndValue($value, $index)
73
    {
74
        if (preg_match('~^([^\']*)\'([^\']*)\'(.*)$~', $value, $matches)) {
75
            if ($index === 0) {
76
                $this->charset = (!empty($matches[1])) ? $matches[1] : $this->charset;
77
                $this->language = (!empty($matches[2])) ? $matches[2] : $this->language;
78
            }
79
            $value = $matches[3];
80
        }
81
        $this->encodedParts[$index] = $value;
82
    }
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
    public function addPart($value, $isEncoded, $index)
99
    {
100
        if (empty($index)) {
101
            $index = 0;
102
        }
103
        if ($isEncoded) {
104
            $this->extractMetaInformationAndValue($value, $index);
105
        } else {
106
            $this->literalParts[$index] = $this->convertEncoding($value);
107
        }
108
    }
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
    private function getNextEncodedValue()
122
    {
123
        $cur = current($this->encodedParts);
124
        $key = key($this->encodedParts);
125
        $running = '';
126
        while ($cur !== false) {
127
            $running .= $cur;
128
            $cur = next($this->encodedParts);
129
            $nKey = key($this->encodedParts);
130
            if ($nKey !== $key + 1) {
131
                break;
132
            }
133
            $key = $nKey;
134
        }
135
        return $this->convertEncoding(
136
            rawurldecode($running),
137
            $this->charset,
138
            true
139
        );
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
    public function getValue()
149
    {
150
        $parts = $this->literalParts;
151
        
152
        reset($this->encodedParts);
153
        ksort($this->encodedParts);
154
        while (current($this->encodedParts) !== false) {
155
            $parts[key($this->encodedParts)] = $this->getNextEncodedValue();
156
        }
157
        
158
        ksort($parts);
159
        return array_reduce(
160
            $parts,
161
            function ($carry, $item) {
162
                return $carry . $item;
163
            },
164
            ''
165
        );
166
    }
167
    
168
    /**
169
     * Returns the name of the parameter.
170
     * 
171
     * @return string
172
     */
173
    public function getName()
174
    {
175
        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
    public function getLanguage()
184
    {
185
        return $this->language;
186
    }
187
}
188