08aff3b4
Mihail
add TableParser a...
|
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
|
<?php
/**
* Created by PhpStorm.
* User: Tsurkanov
* Date: 22.10.2015
* Time: 15:53
*/
namespace yii\multiparser;
use common\components\CustomVarDamp;
abstract class TableParser extends Parser {
/**
* @var array - текущий отпарсенный ряд
*/
protected $row = [];
/** @var int - первая строка с которой начинать парсить */
public $first_line = 0;
/** @var int - последняя строка до которой парсить
* если не указана, то парсинг происходит до конца файла*/
public $last_line = 0;
/** @var int - первая колонка файла с которой начнется парсинг */
public $first_column = 0;
/** @var bool
нужно ли искать автоматически первоую значисмую строку (не пустая строка)
* иначе первая строка будет взята из аттрибута $first_line */
public $auto_detect_first_line = false;
/** @var int - количество значимых колонок, что бы определить первую значимую строку
* используется при автоопределении первой строки*/
public $min_column_quantity = 5;
/** @var int - количество пустых строк, что бы определить конец файла,
такое количеество подряд пустых строк считается концом файла*/
public $empty_lines_quantity = 3;
/** @var int - номер текущей строки парсера */
protected $current_row_number = 0;
protected abstract function isEmptyRow();
protected abstract function isEmptyColumn($column_value);
protected abstract function readRow();
public function read()
{
if ($this->auto_detect_first_line) {
$this->shiftToFirstValuableLine();
}
// будем считать количество пустых строк подряд - при достижении $empty_lines_quantity - считаем что это конец файла и выходим
$empty_lines = 0;
while ( $empty_lines < $this->empty_lines_quantity ) {
// прочтем строку из файла
$this->readRow();
|
08aff3b4
Mihail
add TableParser a...
|
69
70
71
72
73
|
if ( $this->isEmptyRow() ) {
//счетчик пустых строк
$empty_lines++;
continue;
}
|
9d9d876f
Mihail
add xlsx parser i...
|
74
|
|
08aff3b4
Mihail
add TableParser a...
|
75
76
77
78
79
80
81
82
83
84
85
|
// уберем пустые колонки из ряда
$this->filterRow();
$this->adjustRowToSettings( );
// строка не пустая, имеем прочитанный массив значений
$this->current_row_number++;
// для первой строки утановим ключи из заголовка
$this->setKeysFromHeader();
|
9d9d876f
Mihail
add xlsx parser i...
|
86
|
|
08aff3b4
Mihail
add TableParser a...
|
87
88
89
90
91
92
93
94
|
// если у нас установлен лимит, при его достижении прекращаем парсинг
if ( $this->isLastLine() )
break;
// обнуляем счетчик, так как считаюся пустые строки ПОДРЯД
$empty_lines = 0;
$this->result[] = $this->row;
|
9d9d876f
Mihail
add xlsx parser i...
|
95
96
|
$this->row = [];
|
08aff3b4
Mihail
add TableParser a...
|
97
98
99
100
|
}
}
|
08aff3b4
Mihail
add TableParser a...
|
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
|
/**
* определяет первую значимую строку,
* считывается файл пока в нем не встретится строка с непустыми колонками
* в количестве указанном в атрибуте min_column_quantity
* в результате выполнения $current_row_number будет находится на последней незначимой строке
*/
protected function shiftToFirstValuableLine()
{
do {
$this->current_row_number ++;
$this->readRow();
} while( $this->isEmptyRow() );
// @todo - сделать опционально
// код для того что бы парсить первую строку, закомментировано как предполагается что первая значимая строка это заголовок
// $this->current_row_number --;
// $this->file->seek( $this->current_row_number );
}
/**
* @return array - одномерный массив результата парсинга строки
*/
protected function adjustRowToSettings( )
{
|
9d9d876f
Mihail
add xlsx parser i...
|
127
|
|
08aff3b4
Mihail
add TableParser a...
|
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
|
// если есть заголовок, то перед конвертацией его нужно назначить
if ( $this->keys !== NULL ) {
if (count($this->keys) !== count($this->row)) {
throw new \Exception("Ошибка парсинга файла в строке # {$this->current_row_number}. Не соответсвие числа ключевых колонок (заголовка) - числу колонок с данными", 0, 1, $this->file->getBasename(), $this->current_row_number);
}
$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);
}
}
protected function setKeysFromHeader(){
if ( $this->has_header_row ) {
// в файле есть заголовок, но он еще не назначен - назначим
if ($this->keys === NULL) {
$this->keys = array_values( $this->row );
}
}
}
|
9d9d876f
Mihail
add xlsx parser i...
|
158
|
|
08aff3b4
Mihail
add TableParser a...
|
159
160
161
162
163
|
protected function filterRow(){
$this->row = array_filter( $this->row, function($val){
return !$this->isEmptyColumn($val);
});
}
|
9d9d876f
Mihail
add xlsx parser i...
|
164
|
|
08aff3b4
Mihail
add TableParser a...
|
165
166
167
168
169
170
171
172
173
|
protected function isLastLine(){
if ( ( $this->last_line ) && ( $this->current_row_number > $this->last_line ) ) {
return true;
}
return false;
}
}
|