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

Header::formatHeader()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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