Completed
Pull Request — master (#178)
by ignace nyamagana
02:27
created

Validator::convertRecordToUtf8()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
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
namespace League\Csv\Config;
14
15
use DOMDocument;
16
use DOMElement;
17
use InvalidArgumentException;
18
use League\Csv\AbstractCsv;
19
20
/**
21
 * Trait to validate CSV content and properties
22
 *
23
 * @package League.csv
24
 * @since  9.0.0
25
 */
26
trait Validator
27
{
28
    /**
29
     * record name for XML conversion
30
     *
31
     * @var string
32
     */
33
    protected $row_name;
34
35
    /**
36
     * Cell name for XML conversion
37
     *
38
     * @var string
39
     */
40
    protected $cell_name;
41
42
    /**
43
     * Convert a row into a DOMElement
44
     *
45
     * @param string[]    $record Csv record
46
     * @param DOMDocument $doc
47
     *
48
     * @return DOMElement
49
     */
50
    protected function convertRecordToDOMNode(array $record, DOMDocument $doc)
51
    {
52
        $node = $doc->createElement($this->row_name);
53
        foreach ($record as $value) {
54
            $cell = $doc->createElement($this->cell_name);
55
            $cell->appendChild($doc->createTextNode($value));
56
            $node->appendChild($cell);
57
        }
58
59
        return $node;
60
    }
61
62
    /**
63
     * Convert a CSV record to UTF-8
64
     *
65
     * @param string[] $record
66
     * @param string   $input_encoding
67
     *
68
     * @return string[]
69
     */
70
    protected function convertRecordToUtf8(array $record, $input_encoding)
71
    {
72
        $convert = function ($value) use ($input_encoding) {
73
            return iconv($input_encoding, 'UTF-8//TRANSLIT', $value);
74
        };
75
76
        return array_map($convert, $record);
77
    }
78
79
    /**
80
     * Validate an integer
81
     *
82
     * @param int    $int
83
     * @param int    $min_value
84
     * @param string $error_message
85
     *
86
     * @throws InvalidArgumentException If the value is invalid
87
     *
88
     * @return int
89
     */
90
    protected function filterInteger($int, $min_value, $error_message)
91
    {
92
        $int = filter_var($int, FILTER_VALIDATE_INT, ['options' => ['min_range' => $min_value]]);
93
        if (false !== $int) {
94
            return $int;
95
        }
96
97
        throw new InvalidArgumentException($error_message);
98
    }
99
100
    /**
101
     * validate a string
102
     *
103
     * @param mixed $str the value to evaluate as a string
104
     *
105
     * @throws InvalidArgumentException if the submitted data can not be converted to string
106
     *
107
     * @return string
108
     */
109
    protected static function filterString($str)
110
    {
111
        if (is_string($str) || (is_object($str) && method_exists($str, '__toString'))) {
112
            return (string) $str;
113
        }
114
        throw new InvalidArgumentException('Expected data must be a string or stringable');
115
    }
116
117
    /**
118
     * filter CSV Control characters
119
     *
120
     * @param string $str The submitted string
121
     *
122
     * @throws InvalidArgumentException if the character is not valid
123
     *
124
     * @return string
125
     */
126
    protected function filterCsvControl($str)
127
    {
128
        $str = $this->filterString($str);
129
        if (1 == strlen($str)) {
130
            return $str;
131
        }
132
133
        throw new InvalidArgumentException(sprintf('%s is not a single character', $str));
134
    }
135
136
    /**
137
     * Tell whether to use Stream Filter or not to convert the CSV
138
     *
139
     * @param AbstractCsv $csv
140
     *
141
     * @return bool
142
     */
143
    protected function useInternalConverter(AbstractCsv $csv)
144
    {
145
        return !('UTF-8' === $csv->getInputEncoding()
146
            || ($csv->isActiveStreamFilter() && STREAM_FILTER_READ === $csv->getStreamFilterMode()));
147
    }
148
149
    /**
150
     * Strip the BOM character from the record
151
     *
152
     * @param string[] $record
153
     * @param string   $bom
154
     * @param string   $enclosure
155
     *
156
     * @return string[]
157
     */
158
    protected function stripBOM(array $record, $bom, $enclosure)
159
    {
160
        $bom_length = mb_strlen($bom);
161
        if (0 == $bom_length) {
162
            return $record;
163
        }
164
165
        $record[0] = mb_substr($record[0], $bom_length);
166
        if ($record[0][0] === $enclosure && mb_substr($record[0], -1, 1) === $enclosure) {
167
            $record[0] = mb_substr($record[0], 1, -1);
168
        }
169
170
        return $record;
171
    }
172
173
    /**
174
     * Validates the array to be used by the fetchAssoc method
175
     *
176
     * @param string[] $header
177
     *
178
     * @throws InvalidArgumentException If the submitted array fails the assertion
179
     *
180
     * @return string[]
181
     */
182
    protected function filterHeader(array $header)
183
    {
184
        if (empty($header)) {
185
            return $header;
186
        }
187
188
        foreach ($header as &$value) {
189
            $value = $this->filterString($value);
190
        }
191
        unset($value);
192
193
        if (count(array_unique($header)) == count($header)) {
194
            return $header;
195
        }
196
197
        throw new InvalidArgumentException('Use a flat array with unique string values');
198
    }
199
}
200