CsvKeysAwareIterator::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 8
rs 10
cc 1
nc 1
nop 3
1
<?php
2
3
/**
4
 * Platine ETL
5
 *
6
 * Platine ETL is a library to Extract-Transform-Load Data from various sources
7
 *
8
 * This content is released under the MIT License (MIT)
9
 *
10
 * Copyright (c) 2020 Platine ETL
11
 * Copyright (c) 2019 Benoit POLASZEK
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
declare(strict_types=1);
33
34
namespace Platine\Etl\Iterator;
35
36
use IteratorAggregate;
37
use Traversable;
38
39
/**
40
 * @class CsvKeysAwareIterator
41
 * @package Platine\Etl\Iterator
42
 * @implements IteratorAggregate<int|string, mixed>
43
 */
44
class CsvKeysAwareIterator implements IteratorAggregate, CsvIteratorInterface
45
{
46
    /**
47
     * The CSV iterator instance
48
     * @var CsvIteratorInterface<int|string, mixed>
49
     */
50
    protected CsvIteratorInterface $iterator;
51
52
    /**
53
     * The CSV keys (fields)
54
     * @var string[]
55
     */
56
    protected array $keys = [];
57
58
    /**
59
     * Whether to skip first line
60
     * @var bool
61
     */
62
    protected bool $skipFirstLine = true;
63
64
    /**
65
     * Whether already started
66
     * @var bool
67
     */
68
    protected bool $started = false;
69
70
    /**
71
     * Create new instance
72
     * @param CsvIteratorInterface $iterator
73
     * @param string[] $keys
74
     * @param bool $skipFirstLine
75
     */
76
    public function __construct(
77
        CsvIteratorInterface $iterator,
78
        array $keys = [],
79
        bool $skipFirstLine = true
80
    ) {
81
        $this->iterator = $iterator;
82
        $this->keys = $keys;
83
        $this->skipFirstLine = $skipFirstLine;
84
    }
85
86
    /**
87
     * {@inheritodc}
88
     */
89
    public function getIterator(): Traversable
90
    {
91
        foreach ($this->iterator as $value) {
92
            if ($this->started === false) {
93
                $this->started = true;
94
                if (count($this->keys) === 0) {
95
                    $this->keys = $value;
96
                }
97
98
                if ($this->skipFirstLine === true) {
99
                    continue;
100
                }
101
            }
102
103
            yield self::combine($this->keys, $value);
104
        }
105
    }
106
107
    /**
108
     * Combine keys and values
109
     * @param string[] $keys
110
     * @param array<string, mixed> $values
111
     * @return array<int|string, mixed>
112
     */
113
    protected static function combine(array $keys, array $values): array
114
    {
115
        $nbKeys = count($keys);
116
        $nbValues = count($values);
117
118
        if ($nbKeys < $nbValues) {
119
            return (array) array_combine(
120
                $keys,
121
                array_slice(array_values($values), 0, $nbKeys)
122
            );
123
        }
124
125
        if ($nbKeys > $nbValues) {
126
            return (array) array_combine(
127
                $keys,
128
                array_merge($values, (array) array_fill(0, $nbKeys - $nbValues, null))
129
            );
130
        }
131
132
        return (array) array_combine($keys, $values);
133
    }
134
}
135