/
CsvSchema.php
195 lines (178 loc) · 5.79 KB
/
CsvSchema.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
<?php
namespace Concrete\Core\Csv\Import;
class CsvSchema
{
/**
* The row index of the CSV header.
*
* @var int
*/
protected $rowIndex;
/**
* The header cells.
*
* @var string[]
*/
protected $headerCells;
/**
* The map between the CSV field indexes and the object fields/attributes.
*
* @var array keys are the CSV field indexes, values are arrays describing the mapped object fields/attributes
*/
protected $fieldsMap;
/**
* The list of missing headers.
*
* @var string[]
*/
protected $missingHeaders;
/**
* The list of unrecognized headers.
*
* @var string[]
*/
protected $unrecognizedHeaders;
/**
* Initialize the instance.
*
* @param int $rowIndex the row index of the CSV header
* @param string[] $headerCells the list of the header cells
* @param string[]|\Generator $staticHeaders
* @param array $attributesMap
*/
public function __construct($rowIndex, array $headerCells, $staticHeaders, array $attributesMap)
{
$this->rowIndex = (int) $rowIndex;
$this->headerCells = $headerCells;
$this->fieldsMap = [];
$this->missingHeaders = [];
$this->parseStaticHeaders($staticHeaders);
$this->parseAttributeHeaders($attributesMap);
$this->unrecognizedHeaders = array_values(array_diff_key($this->headerCells, $this->fieldsMap));
}
/**
* Get the row index of the CSV header.
*
* @return int
*/
public function getRowIndex()
{
return $this->rowIndex;
}
/**
* Do some of the headers have been recognized?
*
* @return bool
*/
public function someHeaderRecognized()
{
return !empty($this->fieldsMap);
}
/**
* Get the list of missing headers.
*
* @return string[]
*/
public function getMissingHeaders()
{
return $this->missingHeaders;
}
/**
* Get the values of the cells associated to the static headers.
*
* @param array $cells
*
* @return array keys are the static field names, values are the field values (strings)
*/
public function getStaticValues(array $cells)
{
$result = [];
foreach ($this->fieldsMap as $cellIndex => $info) {
if ($info['kind'] === 'staticHeader') {
$fieldName = $info['staticHeaderName'];
$result[$fieldName] = isset($cells[$cellIndex]) ? $cells[$cellIndex] : '';
}
}
return $result;
}
/**
* Get the values of the cells associated to the attributes.
*
* @param array $cells
*
* @return array keys are the index of the attribute keys, values are the field values.
* In case of single-line attributes, values are strings.
* In case of multi-column attributes, values are arrays whose keys are the sub-headers and values the strings.
*/
public function getAttributesValues(array $cells)
{
$result = [];
foreach ($this->fieldsMap as $cellIndex => $info) {
switch ($info['kind']) {
case 'singleAttributeHeader':
$attributeIndex = $info['attributeIndex'];
$result[$attributeIndex] = isset($cells[$cellIndex]) ? $cells[$cellIndex] : '';
break;
case 'multipleAttributeHeader':
$attributeIndex = $info['attributeIndex'];
$attributeSubHeader = $info['attributeSubHeader'];
$value = isset($cells[$cellIndex]) ? $cells[$cellIndex] : '';
if (isset($result[$attributeIndex])) {
$result[$attributeIndex][$attributeSubHeader] = $value;
} else {
$result[$attributeIndex] = [$attributeSubHeader => $value];
}
break;
}
}
return $result;
}
/**
* Get the list of unrecognized headers.
*
* @return string[]
*/
public function getUnrecognizedHeaders()
{
return $this->unrecognizedHeaders;
}
/**
* @param string[]|\Generator $staticHeaders
*/
private function parseStaticHeaders($staticHeaders)
{
foreach ($staticHeaders as $staticHeader) {
$index = array_search($staticHeader, $this->headerCells, true);
if ($index === false) {
$this->missingHeaders[] = $staticHeader;
} else {
$this->fieldsMap[$index] = ['kind' => 'staticHeader', 'staticHeaderName' => $staticHeader];
}
}
}
/**
* @param array $attributesMap
*/
private function parseAttributeHeaders($attributesMap)
{
foreach ($attributesMap as $attributeIndex => $attributeHeaders) {
if (is_string($attributeHeaders)) {
$index = array_search($attributeHeaders, $this->headerCells, true);
if ($index === false) {
$this->missingHeaders[] = $attributeHeaders;
} else {
$this->fieldsMap[$index] = ['kind' => 'singleAttributeHeader', 'attributeIndex' => $attributeIndex];
}
} else {
foreach ($attributeHeaders as $attributeHeader => $attributeSubHeader) {
$index = array_search($attributeHeader, $this->headerCells, true);
if ($index === false) {
$this->missingHeaders[] = $attributeHeader;
} else {
$this->fieldsMap[$index] = ['kind' => 'multipleAttributeHeader', 'attributeIndex' => $attributeIndex, 'attributeSubHeader' => $attributeSubHeader];
}
}
}
}
}
}