Completed
Push — master ( c51846...2d4307 )
by ignace nyamagana
04:22 queued 02:03
created

Encoder::filterEncoding()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 2
nop 1
dl 0
loc 10
ccs 6
cts 6
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
* This file is part of the League.csv library
4
*
5
* @license http://opensource.org/licenses/MIT
6
* @link https://github.com/thephpleague/csv/
7
* @version 9.0.0
8
* @package League.csv
9
*
10
* For the full copyright and license information, please view the LICENSE
11
* file that was distributed with this source code.
12
*/
13
declare(strict_types=1);
14
15
namespace League\Csv;
16
17
use Iterator;
18
use League\Csv\Exception\InvalidArgumentException;
19
use Traversable;
20
21
/**
22
 *  A class to encode your CSV records collection
23
 *
24
 * @package League.csv
25
 * @since   9.0.0
26
 * @author  Ignace Nyamagana Butera <[email protected]>
27
 */
28
class Encoder
29
{
30
    use ValidatorTrait;
31
32
    /**
33
     * The records input encoding charset
34
     *
35
     * @var string
36
     */
37
    protected $input_encoding = 'UTF-8';
38
39
    /**
40
     * The records output encoding charset
41
     *
42
     * @var string
43
     */
44
    protected $output_encoding = 'UTF-8';
45
46
    /**
47
     * Enable using the class as a formatter for the {@link Writer}
48
     *
49
     * @see encodeOne
50
     *
51
     * @param array $record CSV record
52
     *
53
     * @return string[]
54
     */
55 2
    public function __invoke(array $record): array
56
    {
57 2
        return $this->encodeOne($record);
58
    }
59
60
    /**
61
     * Encode a CSV record
62
     *
63
     * @param array $record CSV record
64
     *
65
     * @return string[]
66
     */
67 2
    public function encodeOne(array $record): array
68
    {
69 2
        if ($this->output_encoding !== $this->input_encoding) {
70 2
            array_walk($record, [$this, 'encodeField']);
71
        }
72
73 2
        return $record;
74
    }
75
76
    /**
77
     * Walker method to convert the offset and the value of a CSV record field
78
     *
79
     * @param string|null &$value
80
     * @param string|int  &$offset
81
     */
82 6
    protected function encodeField(&$value, &$offset)
83
    {
84 6
        if (null !== $value) {
85 6
            $value = mb_convert_encoding((string) $value, $this->output_encoding, $this->input_encoding);
86
        }
87
88 6
        if (!is_int($offset)) {
89 6
            $offset = mb_convert_encoding((string) $offset, $this->output_encoding, $this->input_encoding);
90
        }
91 6
    }
92
93
    /**
94
     * Convert Csv file into UTF-8
95
     *
96
     * @param array|Traversable $records the CSV records collection
97
     *
98
     * @return array|Iterator
99
     */
100 6
    public function encodeAll($records)
101
    {
102 6
        $records = $this->filterIterable($records, __METHOD__);
103 6
        if ($this->output_encoding === $this->input_encoding) {
104 2
            return $records;
105
        }
106
107 4
        $convert = function (array $record): array {
108 4
            array_walk($record, [$this, 'encodeField']);
109 4
            return $record;
110 2
        };
111
112 4
        return is_array($records) ? array_map($convert, $records) : new MapIterator($records, $convert);
113
    }
114
115
    /**
116
     * Sets the records input encoding charset
117
     *
118
     * @param string $encoding
119
     *
120
     * @return static
121
     */
122 8
    public function inputEncoding(string $encoding): self
123
    {
124 8
        $encoding = $this->filterEncoding($encoding);
125 6
        if ($encoding === $this->input_encoding) {
126 2
            return $this;
127
        }
128
129 4
        $clone = clone $this;
130 4
        $clone->input_encoding = $encoding;
131
132 4
        return $clone;
133
    }
134
135
    /**
136
     * Filter encoding charset
137
     *
138
     * @param string $encoding
139
     *
140
     * @throws InvalidArgumentException if the charset is malformed
141
     *
142
     * @return string
143
     */
144 10
    protected function filterEncoding(string $encoding)
145
    {
146 10
        $encoding = strtoupper(str_replace('_', '-', $encoding));
147 10
        $test = filter_var($encoding, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
148 10
        if ($test === $encoding && $encoding != '') {
149 8
            return $encoding;
150
        }
151
152 2
        throw new InvalidArgumentException('Invalid Character Error');
153
    }
154
155
    /**
156
     * Sets the records output encoding charset
157
     *
158
     * @param string $encoding
159
     *
160
     * @return static
161
     */
162 4
    public function outputEncoding(string $encoding): self
163
    {
164 4
        $encoding = $this->filterEncoding($encoding);
165 4
        if ($encoding === $this->output_encoding) {
166 2
            return $this;
167
        }
168
169 4
        $clone = clone $this;
170 4
        $clone->output_encoding = $encoding;
171
172 4
        return $clone;
173
    }
174
}
175