1e991822
Mihail
csv parser with e...
|
1
2
|
<?php
/**
|
1e991822
Mihail
csv parser with e...
|
3
|
|
40ff24a1
Mihail
refactor CsvParse...
|
4
|
*/
|
036717a1
Mihail
add error excepti...
|
5
|
namespace yii\multiparser;
|
dc10d651
Mihail
add value filter ...
|
6
|
|
1e991822
Mihail
csv parser with e...
|
7
|
|
474f35bf
Mihail
add DynamicFormHe...
|
8
9
10
11
|
/**
* Class CsvParser
* @package yii\multiparser
*/
|
37656b1f
Mihail
add parser interf...
|
12
|
class CsvParser implements ParserInterface
|
999b9326
Mihail
add detectStartPo...
|
13
|
{
|
1e991822
Mihail
csv parser with e...
|
14
|
|
1e991822
Mihail
csv parser with e...
|
15
|
|
40ff24a1
Mihail
refactor CsvParse...
|
16
17
|
/** @var bool
имеет ли файл заголовок который будет установлен ключами возвращемого массива*/
|
e55d56cc
Mihail
add draft version...
|
18
|
public $hasHeaderRow = false;
|
40ff24a1
Mihail
refactor CsvParse...
|
19
20
21
|
/** @var array - массив с заголовком,
* если не указан и установлено свойство $hasHeaderRow - будет определен автоматически */
public $keys;
|
1e991822
Mihail
csv parser with e...
|
22
|
|
40ff24a1
Mihail
refactor CsvParse...
|
23
|
/** @var экземляр SplFileObject читаемого файла */
|
e55d56cc
Mihail
add draft version...
|
24
|
public $file;
|
1e991822
Mihail
csv parser with e...
|
25
|
|
40ff24a1
Mihail
refactor CsvParse...
|
26
|
/** @var int - первая строка с которой начинать парсить */
|
e55d56cc
Mihail
add draft version...
|
27
|
public $first_line = 0;
|
1e991822
Mihail
csv parser with e...
|
28
|
|
40ff24a1
Mihail
refactor CsvParse...
|
29
30
31
32
33
|
/** @var int - последняя строка до которой парсить
* если не указана, то парсинг происходит до конца файла*/
public $last_line = 0;
/** @var int - первая колонка файла с которой начнется парсинг */
|
e55d56cc
Mihail
add draft version...
|
34
|
public $first_column = 0;
|
b13b1c83
Mihail
final version par...
|
35
|
|
40ff24a1
Mihail
refactor CsvParse...
|
36
|
/** @var string - разделитель csv */
|
e55d56cc
Mihail
add draft version...
|
37
|
public $delimiter = ';';
|
40ff24a1
Mihail
refactor CsvParse...
|
38
39
40
41
42
43
44
45
|
/** @var bool
нужно ли искать автоматически первоую значисмую строку (не пустая строка)
* иначе первая строка будет взята из аттрибута $first_line */
public $auto_detect_first_line = false;
/** @var int - количество значимых колонок, что бы определить первую значимую строку
* используется при автоопределении первой строки*/
|
e55d56cc
Mihail
add draft version...
|
46
|
public $min_column_quantity = 5;
|
dc10d651
Mihail
add value filter ...
|
47
|
|
74072a2a
Mihail
add first version...
|
48
49
50
51
|
/** @var array - конфигурация конвертера значений */
public $converter_conf = [];
/** @var array - конвертер созданный по конфигурации */
public $converter = NULL;
|
5c710262
Mihail
edit csv parser -...
|
52
|
|
474f35bf
Mihail
add DynamicFormHe...
|
53
|
|
40ff24a1
Mihail
refactor CsvParse...
|
54
|
/**
|
74072a2a
Mihail
add first version...
|
55
|
* метод устанвливает нужные настройки объекта SplFileObject, для работы с csv
|
40ff24a1
Mihail
refactor CsvParse...
|
56
|
*/
|
e55d56cc
Mihail
add draft version...
|
57
58
|
public function setup()
{
|
999b9326
Mihail
add detectStartPo...
|
59
60
61
|
$this->file->setCsvControl($this->delimiter);
$this->file->setFlags(\SplFileObject::READ_CSV);
$this->file->setFlags(\SplFileObject::SKIP_EMPTY);
|
aa518ad3
Mihail
finishing with co...
|
62
|
|
40ff24a1
Mihail
refactor CsvParse...
|
63
64
|
if ($this->auto_detect_first_line) {
$this->shiftToFirstValuableLine();
|
e55d56cc
Mihail
add draft version...
|
65
|
}
|
74072a2a
Mihail
add first version...
|
66
67
|
$this->setupConverter();
|
1e991822
Mihail
csv parser with e...
|
68
69
|
}
|
40ff24a1
Mihail
refactor CsvParse...
|
70
|
/**
|
74072a2a
Mihail
add first version...
|
71
72
73
74
75
|
* устанавливает конвертер значений согласно конфигурационным настройкам
*/
public function setupConverter()
{
if (!count($this->converter_conf)) {
|
d21c5c5f
Mihail
XMLparser - read ...
|
76
|
$this->converter = new Converter();
|
74072a2a
Mihail
add first version...
|
77
78
79
80
81
|
if ($this->hasHeaderRow) {
// если у файла есть заголовок, то в результате имеем ассоциативный массив
$this->converter_conf['hasKey'] = 1;
}
$this->converter->configuration = $this->converter_conf;
|
aa518ad3
Mihail
finishing with co...
|
82
|
|
74072a2a
Mihail
add first version...
|
83
84
85
86
87
|
}
}
/**
|
40ff24a1
Mihail
refactor CsvParse...
|
88
89
90
91
92
93
|
* определяет первую значимую строку,
* считывается файл пока в нем не встретится строка с непустыми колонками
* в количестве указанном в атрибуте min_column_quantity
* в результате выполнения курсор ресурса будет находится на последней незначимой строке
*/
protected function shiftToFirstValuableLine()
|
e55d56cc
Mihail
add draft version...
|
94
|
{
|
e55d56cc
Mihail
add draft version...
|
95
|
|
40ff24a1
Mihail
refactor CsvParse...
|
96
97
98
|
$finish = false;
while (!$finish) {
|
999b9326
Mihail
add detectStartPo...
|
99
100
|
$j = 0;
$row = $this->readRow();
|
999b9326
Mihail
add detectStartPo...
|
101
102
|
if ($row === false) {
continue;
|
e55d56cc
Mihail
add draft version...
|
103
|
}
|
999b9326
Mihail
add detectStartPo...
|
104
|
|
999b9326
Mihail
add detectStartPo...
|
105
106
107
108
109
110
111
|
for ($i = 1; $i <= count($row); $i++) {
if ($row[$i - 1] <> '') {
$j++;
}
if ($j >= $this->min_column_quantity) {
|
40ff24a1
Mihail
refactor CsvParse...
|
112
|
break 2;
|
999b9326
Mihail
add detectStartPo...
|
113
|
}
|
e55d56cc
Mihail
add draft version...
|
114
115
|
}
}
|
e55d56cc
Mihail
add draft version...
|
116
|
}
|
1e991822
Mihail
csv parser with e...
|
117
118
|
/**
|
40ff24a1
Mihail
refactor CsvParse...
|
119
120
|
* @return array - итоговый двумерный массив с результатом парсинга
* метод считывает с открытого файла данные построчно
|
1e991822
Mihail
csv parser with e...
|
121
122
123
|
*/
public function read()
{
|
aa518ad3
Mihail
finishing with co...
|
124
|
|
1e991822
Mihail
csv parser with e...
|
125
|
$return = [];
|
40ff24a1
Mihail
refactor CsvParse...
|
126
127
|
$current_line = 0;
|
e774f057
Mihail
work with custome...
|
128
|
//$this->keys = NULL;
|
40ff24a1
Mihail
refactor CsvParse...
|
129
|
|
1e991822
Mihail
csv parser with e...
|
130
|
while (($row = $this->readRow()) !== FALSE) {
|
40ff24a1
Mihail
refactor CsvParse...
|
131
|
$current_line++;
|
1e991822
Mihail
csv parser with e...
|
132
|
if ($this->hasHeaderRow) {
|
dc10d651
Mihail
add value filter ...
|
133
134
|
if ($this->keys === NULL) {
$this->keys = array_values($row);
|
1e991822
Mihail
csv parser with e...
|
135
136
|
} else {
|
dc10d651
Mihail
add value filter ...
|
137
|
if (count($this->keys) !== count($row)) {
|
1e991822
Mihail
csv parser with e...
|
138
|
//
|
74072a2a
Mihail
add first version...
|
139
|
throw new \ErrorException("Invalid columns detected on line # {$current_line}", 0, 1, $this->file->getBasename(), $current_line);
|
1e991822
Mihail
csv parser with e...
|
140
141
|
}
|
dc10d651
Mihail
add value filter ...
|
142
|
$return[] = array_combine($this->keys, $row);
|
1e991822
Mihail
csv parser with e...
|
143
|
}
|
74072a2a
Mihail
add first version...
|
144
|
} else {
|
1e991822
Mihail
csv parser with e...
|
145
146
|
$return[] = $row;
}
|
40ff24a1
Mihail
refactor CsvParse...
|
147
148
|
// если у нас установлен лимит, при его достижении прекращаем парсинг
if (($this->last_line) && ($current_line > $this->last_line)) {
|
999b9326
Mihail
add detectStartPo...
|
149
150
151
|
break;
}
|
1e991822
Mihail
csv parser with e...
|
152
153
154
|
}
$this->closeHandler();
|
1e991822
Mihail
csv parser with e...
|
155
156
157
|
return $return;
}
|
2957209c
Mihail
csv parser - add ...
|
158
|
|
dfeb2d10
Mihail
edit universal cs...
|
159
|
protected function closeHandler()
|
1e991822
Mihail
csv parser with e...
|
160
|
{
|
2957209c
Mihail
csv parser - add ...
|
161
|
$this->file = NULL;
|
1e991822
Mihail
csv parser with e...
|
162
163
|
}
|
40ff24a1
Mihail
refactor CsvParse...
|
164
165
166
|
/**
* @return array - одномерный массив результата парсинга строки
*/
|
dfeb2d10
Mihail
edit universal cs...
|
167
|
protected function readRow()
|
1e991822
Mihail
csv parser with e...
|
168
|
{
|
dfeb2d10
Mihail
edit universal cs...
|
169
|
|
999b9326
Mihail
add detectStartPo...
|
170
|
$row = $this->file->fgetcsv();
|
74072a2a
Mihail
add first version...
|
171
172
|
if (is_array($row)) {
// попытаемся конвертировать прочитанные занчения согдасно конфигурации котнвертера значений
|
aa518ad3
Mihail
finishing with co...
|
173
|
// \common\components\CustomVarDamp::dump($row,1);
|
74072a2a
Mihail
add first version...
|
174
|
$row = $this->convert($row);
|
aa518ad3
Mihail
finishing with co...
|
175
|
// \common\components\CustomVarDamp::dump($row,2);
|
74072a2a
Mihail
add first version...
|
176
|
if ($this->first_column) {
|
40ff24a1
Mihail
refactor CsvParse...
|
177
|
|
74072a2a
Mihail
add first version...
|
178
|
$row = array_slice($row, $this->first_column);
|
40ff24a1
Mihail
refactor CsvParse...
|
179
|
|
74072a2a
Mihail
add first version...
|
180
|
}
|
dfeb2d10
Mihail
edit universal cs...
|
181
|
}
|
999b9326
Mihail
add detectStartPo...
|
182
183
|
if (is_null($row))
$row = false;
|
dc10d651
Mihail
add value filter ...
|
184
|
|
dfeb2d10
Mihail
edit universal cs...
|
185
|
return $row;
|
1e991822
Mihail
csv parser with e...
|
186
187
188
|
}
|
74072a2a
Mihail
add first version...
|
189
190
191
192
193
194
195
196
197
198
|
/**
* @param $arr
* @return mixed
* преобразовует значения прочитанного массива в нужные типы, согласно конфигурации конвертера
*/
protected function convert($arr)
{
$result = $arr;
$converter = $this->converter;
|
74072a2a
Mihail
add first version...
|
199
200
|
if (!is_null($converter)) {
|
aa518ad3
Mihail
finishing with co...
|
201
|
$result = $converter->convertByConfiguration( $arr );
|
74072a2a
Mihail
add first version...
|
202
203
204
205
206
207
208
|
}
return $result;
}
|
1e991822
Mihail
csv parser with e...
|
209
210
|
}
|