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

Header::setHeader()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 9
nc 3
nop 1
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 InvalidArgumentException;
16
use League\Csv\AbstractCsv;
17
use LimitIterator;
18
use SplFileObject;
19
20
/**
21
 * A trait to configure and check CSV header
22
 *
23
 * @package League.csv
24
 * @since  9.0.0
25
 *
26
 */
27
trait Header
28
{
29
    /**
30
     * Csv Header Info
31
     *
32
     * @var array|int
33
     */
34
    protected $header = [];
35
36
    /**
37
     * Returns the inner SplFileObject
38
     *
39
     * @return SplFileObject
40
     */
41
    abstract public function getIterator();
42
43
    /**
44
     * Returns the current field enclosure
45
     *
46
     * @return string
47
     */
48
    abstract public function getEnclosure();
49
50
    /**
51
     * Returns the BOM sequence of the given CSV
52
     *
53
     * @return string
54
     */
55
    abstract public function getInputBOM();
56
57
    /**
58
     * Tell whether to use Stream Filter or not to convert the CSV
59
     *
60
     * @return bool
61
     */
62
    abstract protected function useInternalConverter(AbstractCsv $csv);
63
64
    /**
65
     * Convert a CSV record to UTF-8
66
     *
67
     * @param array  $record
68
     * @param string $input_encoding
69
     *
70
     * @return array
71
     */
72
    abstract protected function convertRecordToUtf8(array $record, $input_encoding);
73
74
    /**
75
     * Strip the BOM character from the record
76
     *
77
     * @param string[] $record
78
     * @param string   $bom
79
     * @param string   $enclosure
80
     *
81
     * @return array
82
     */
83
    abstract protected function stripBOM(array $record, $bom, $enclosure);
84
85
    /**
86
     * Gets the source CSV encoding charset
87
     *
88
     * @return string
89
     */
90
    abstract public function getInputEncoding();
91
92
    /**
93
     * Validate an integer
94
     *
95
     * @param int    $int
96
     * @param int    $minValue
97
     * @param string $errorMessage
98
     *
99
     * @throws InvalidArgumentException If the value is invalid
100
     *
101
     * @return int
102
     */
103
    abstract protected function validateInteger($int, $minValue, $errorMessage);
104
105
    /**
106
     * validate a string
107
     *
108
     * @param mixed $str the value to evaluate as a string
109
     *
110
     * @throws InvalidArgumentException if the submitted data can not be converted to string
111
     *
112
     * @return string
113
     */
114
    abstract protected function validateString($str);
115
116
    /**
117
     * Tell whether the current header is internal
118
     * or user submitted
119
     *
120
     * @return int|null
121
     */
122
    public function getHeaderOffset()
123
    {
124
        if (is_array($this->header)) {
125
            return null;
126
        }
127
128
        return $this->header;
129
    }
130
131
    /**
132
     * Returns the CSV header
133
     *
134
     * @return array
135
     */
136
    public function getHeader()
137
    {
138
        if (is_array($this->header)) {
139
            return $this->header;
140
        }
141
142
        return $this->getHeaderFromDocument();
143
    }
144
145
    /**
146
     * Get the Header from a CSV record
147
     *
148
     * @return array
149
     */
150
    protected function getHeaderFromDocument()
151
    {
152
        $iterator = new LimitIterator($this->getIterator(), $this->header);
153
        $iterator->rewind();
154
        $header = $iterator->current();
155
        if ($iterator->key() !== $this->header) {
156
            throw new InvalidArgumentException('the select offset does not exist');
157
        }
158
159
        if (0 !== $this->header) {
160
            return $header;
161
        }
162
163
        return $this->formatHeader($header, $this->getInputBOM(), $this->getEnclosure());
164
    }
165
166
    /**
167
     * Format the Document Header
168
     *
169
     * @param string[] $header
170
     * @param string   $bom
171
     * @param string   $enclosure
172
     *
173
     * @return string[]
174
     */
175
    protected function formatHeader(array $header, $bom, $enclosure)
176
    {
177
        $header = $this->stripBOM($header, $bom, $enclosure);
178
        if (!$this->useInternalConverter($this)) {
179
            return $header;
180
        }
181
182
        return $this->convertRecordToUtf8($header, $this->getInputEncoding());
183
    }
184
185
    /**
186
     * Selects the array to be used as key for the fetchAssoc method
187
     *
188
     * @param int|null|array $offset_or_keys the assoc key OR the row Index to be used
189
     *                                       as the key index
190
     *
191
     * @return $this
192
     */
193
    public function setHeader($offset_or_keys)
194
    {
195
        if (is_array($offset_or_keys)) {
196
            $this->header = $this->validateHeader($offset_or_keys);
197
            return $this;
198
        }
199
200
        if (null === $offset_or_keys) {
201
            $this->header = [];
202
            return $this;
203
        }
204
205
        $this->header = $this->validateInteger($offset_or_keys, 0, 'the header offset is invalid');
206
        return $this;
207
    }
208
209
    /**
210
     * Validates the array to be used by the fetchAssoc method
211
     *
212
     * @param array $keys
213
     *
214
     * @throws InvalidArgumentException If the submitted array fails the assertion
215
     *
216
     * @return array
217
     */
218
    protected function validateHeader(array $keys)
219
    {
220
        if (empty($keys)) {
221
            return $keys;
222
        }
223
224
        foreach ($keys as &$value) {
225
            $value = $this->validateString($value);
226
        }
227
        unset($value);
228
229
        if (count(array_unique($keys)) == count($keys)) {
230
            return $keys;
231
        }
232
233
        throw new InvalidArgumentException('Use a flat array with unique string values');
234
    }
235
}
236