ad2e91f7
Mihail
move multyparser ...
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?php
/**
* Created by PhpStorm.
* User: Tsurkanov
* Date: 22.10.2015
* Time: 15:53
*/
namespace common\components\parsers;
use common\components\CustomVarDamp;
abstract class TableParser extends Parser
{
|
ad2e91f7
Mihail
move multyparser ...
|
16
17
|
/**
* @var array - текущий отпарсенный ряд
|
2d4b1514
Mihail
adapted xls parser
|
18
19
20
|
*если есть ключи, то колонки с пустыми значениями будут пропускаться (из ряда такие значения будут удаляться),
* например если в файле вторая колонка пустая то она будет удалена
* в остальных случаях парсятся все колонки (не проверяется - пустая ли колонка) и попадёт в итоговый массив
|
ad2e91f7
Mihail
move multyparser ...
|
21
22
23
|
*/
protected $row = [];
|
2d4b1514
Mihail
adapted xls parser
|
24
25
26
27
28
|
/** @var int - первая строка с которой начинать парсить
* эта строка будет считаться первой значимой строкой
* если установлен аттрибут $has_header_row,
* тогда следующая строка будет считаться заголовком и будет пропущена
*/
|
ad2e91f7
Mihail
move multyparser ...
|
29
30
31
32
33
34
35
36
37
38
39
|
public $first_line = 0;
/** @var int - последняя строка до которой парсить
* если не указана, то парсинг происходит до конца файла*/
public $last_line = 0;
/** @var int - первая колонка файла с которой начнется парсинг */
public $first_column = 0;
/** @var bool
|
2d4b1514
Mihail
adapted xls parser
|
40
41
42
43
44
|
* имеет ли файл заголовок в первой значимой строке
* true - первая значимая строка будет пропущена
*/
public $has_header_row = true;
|
ad2e91f7
Mihail
move multyparser ...
|
45
46
47
48
49
50
51
52
53
54
55
56
57
|
/** @var int - количество значимых колонок, что бы определить первую значимую строку
* используется при автоопределении первой строки*/
public $min_column_quantity = 5;
/** @var int - количество пустых строк, что бы определить конец файла,
* такое количеество подряд пустых строк считается концом файла*/
public $empty_lines_quantity = 3;
/** @var int - номер текущей строки парсера */
protected $current_row_number = 0;
|
ad2e91f7
Mihail
move multyparser ...
|
58
59
60
61
62
63
64
65
66
|
protected abstract function isEmptyColumn($column_value);
protected abstract function readRow();
protected abstract function setResult();
public function read()
{
|
2d4b1514
Mihail
adapted xls parser
|
67
68
69
70
71
|
// получим первую значимую строку
$this->shiftToFirstValuableLine();
// первый проход, строка прочитана в shiftToFirstValuableLine
$first_circle = true;
|
ad2e91f7
Mihail
move multyparser ...
|
72
73
74
75
|
// будем считать количество пустых строк подряд - при достижении $empty_lines_quantity - считаем что это конец файла и выходим
$empty_lines = 0;
while ($empty_lines < $this->empty_lines_quantity) {
|
ad2e91f7
Mihail
move multyparser ...
|
76
|
|
2d4b1514
Mihail
adapted xls parser
|
77
78
79
|
// прочтем строку из файла, если это не первый проход
if (!$first_circle){
$this->readRow();
|
ad2e91f7
Mihail
move multyparser ...
|
80
81
|
}
|
2d4b1514
Mihail
adapted xls parser
|
82
83
|
$first_circle = false;
|
ad2e91f7
Mihail
move multyparser ...
|
84
85
86
87
88
|
// уберем пустые колонки из ряда
if ($this->keys === NULL) {
$this->filterRow();
}
|
2d4b1514
Mihail
adapted xls parser
|
89
90
91
92
93
94
|
if ($this->isEmptyRow()) {
//счетчик пустых строк
$empty_lines++;
$this->current_row_number++;
continue;
}
|
ad2e91f7
Mihail
move multyparser ...
|
95
|
|
2d4b1514
Mihail
adapted xls parser
|
96
|
// запустим конвертирование
|
ad2e91f7
Mihail
move multyparser ...
|
97
98
|
$this->adjustRowToSettings();
|
2d4b1514
Mihail
adapted xls parser
|
99
100
|
// установим отпарсенную строку в итоговый массив результата
$this->setResult();
|
ad2e91f7
Mihail
move multyparser ...
|
101
102
103
|
// строка не пустая, имеем прочитанный массив значений
$this->current_row_number++;
|
ad2e91f7
Mihail
move multyparser ...
|
104
105
106
107
108
109
|
// если у нас установлен лимит, при его достижении прекращаем парсинг
if ($this->isLastLine())
break;
// обнуляем счетчик, так как считаюся пустые строки ПОДРЯД
$empty_lines = 0;
|
ad2e91f7
Mihail
move multyparser ...
|
110
|
}
|
ad2e91f7
Mihail
move multyparser ...
|
111
112
113
114
115
|
}
/**
* определяет первую значимую строку,
* считывается файл пока в нем не встретится строка с непустыми колонками
|
2d4b1514
Mihail
adapted xls parser
|
116
117
|
* или пока не дойдет до first_line
* пропускает заголовок если он указан
|
ad2e91f7
Mihail
move multyparser ...
|
118
119
120
|
*/
protected function shiftToFirstValuableLine()
{
|
2d4b1514
Mihail
adapted xls parser
|
121
|
// читаем пока не встретим значимую строку, или пока не дойдем до first_line
|
ad2e91f7
Mihail
move multyparser ...
|
122
|
do {
|
ad2e91f7
Mihail
move multyparser ...
|
123
124
|
$this->current_row_number++;
$this->readRow();
|
2d4b1514
Mihail
adapted xls parser
|
125
|
} while ( $this->isEmptyRow() && ( $this->first_line < $this->current_row_number ) );
|
ad2e91f7
Mihail
move multyparser ...
|
126
|
|
2d4b1514
Mihail
adapted xls parser
|
127
128
129
130
131
|
// если указан заголовок, то его мы тоже пропускаем (читаем далее)
if( $this->has_header_row ) {
$this->current_row_number++;
$this->readRow();
}
|
ad2e91f7
Mihail
move multyparser ...
|
132
133
134
135
136
137
138
|
}
/**
* @return array - одномерный массив результата парсинга строки
*/
protected function adjustRowToSettings()
{
|
ad2e91f7
Mihail
move multyparser ...
|
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
// если есть заголовок, то перед конвертацией его нужно назначить
if ($this->keys !== NULL) {
// adjust row to keys
$this->adjustRowToKeys();
// назначим заголовок
$this->row = array_combine($this->keys, $this->row);
}
// попытаемся конвертировать прочитанные значения согласно конфигурации котнвертера значений
$this->row = $this->convert($this->row);
// обрежем массив к первой значимой колонке
if ($this->first_column) {
$this->row = array_slice($this->row, $this->first_column);
}
}
|
2d4b1514
Mihail
adapted xls parser
|
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
|
protected function isEmptyRow(){
$is_empty = false;
if ( empty( $this->row ) ) {
return true;
}
if ( count( $this->row ) < $this->min_column_quantity ) {
return true;
}
$j = 0;
for ($i = 1; $i <= count( $this->row ); $i++) {
if ( !isset( $this->row[ $i - 1 ] ) ) {
continue;
}
if ( $this->isEmptyColumn( $this->row[$i - 1] ) ) {
$j++;
}
if ( $j >= $this->min_column_quantity ) {
$is_empty = true;
break;
|
ad2e91f7
Mihail
move multyparser ...
|
184
185
|
}
}
|
2d4b1514
Mihail
adapted xls parser
|
186
187
|
return $is_empty;
|
ad2e91f7
Mihail
move multyparser ...
|
188
189
|
}
|
2d4b1514
Mihail
adapted xls parser
|
190
191
|
|
ad2e91f7
Mihail
move multyparser ...
|
192
193
|
protected function filterRow()
{
|
2d4b1514
Mihail
adapted xls parser
|
194
195
|
// нет строки - нет фильтрации
if ( empty( $this->row ) ) {
|
ad2e91f7
Mihail
move multyparser ...
|
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
return;
}
$this->row = array_filter($this->row, function ($val) {
return !$this->isEmptyColumn($val);
});
}
protected function isLastLine()
{
if (($this->last_line) && ($this->current_row_number > $this->last_line)) {
return true;
}
return false;
}
protected function adjustRowToKeys()
{
//уберем из ряда те колонки которых нет в ключах
$this->row = array_intersect_key($this->row, $this->keys);
$keys_count = count($this->keys);
$column_count = count($this->row);
if ($keys_count != $column_count) {
// найдем колонки которых нет в ряде но есть ключах
$arr_diff = array_diff_key($this->keys, $this->row);
foreach ($arr_diff as $key => $value) {
// колонки которых нет в ряде но есть ключах, добавим их с пустым значением
$this->row[$key] = '';
}
}
}
}
|