Commit a684f314ab18562194ce5cd45eeda81afaebd5ad
1 parent
58f734e6
add adjustRowToKeys function
Showing
2 changed files
with
68 additions
and
35 deletions
Show diff stats
lib/TableParser.php
... | ... | @@ -11,7 +11,8 @@ namespace yii\multiparser; |
11 | 11 | |
12 | 12 | use common\components\CustomVarDamp; |
13 | 13 | |
14 | -abstract class TableParser extends Parser { | |
14 | +abstract class TableParser extends Parser | |
15 | +{ | |
15 | 16 | |
16 | 17 | |
17 | 18 | /** |
... | ... | @@ -39,7 +40,7 @@ abstract class TableParser extends Parser { |
39 | 40 | * используется при автоопределении первой строки*/ |
40 | 41 | public $min_column_quantity = 5; |
41 | 42 | /** @var int - количество пустых строк, что бы определить конец файла, |
42 | - такое количеество подряд пустых строк считается концом файла*/ | |
43 | + * такое количеество подряд пустых строк считается концом файла*/ | |
43 | 44 | public $empty_lines_quantity = 3; |
44 | 45 | |
45 | 46 | |
... | ... | @@ -64,11 +65,11 @@ abstract class TableParser extends Parser { |
64 | 65 | |
65 | 66 | // будем считать количество пустых строк подряд - при достижении $empty_lines_quantity - считаем что это конец файла и выходим |
66 | 67 | $empty_lines = 0; |
67 | - while ( $empty_lines < $this->empty_lines_quantity ) { | |
68 | + while ($empty_lines < $this->empty_lines_quantity) { | |
68 | 69 | // прочтем строку из файла |
69 | 70 | $this->readRow(); |
70 | 71 | |
71 | - if ( $this->isEmptyRow() ) { | |
72 | + if ($this->isEmptyRow()) { | |
72 | 73 | //счетчик пустых строк |
73 | 74 | //CustomVarDamp::dump($this->current_row_number); |
74 | 75 | $empty_lines++; |
... | ... | @@ -76,21 +77,24 @@ abstract class TableParser extends Parser { |
76 | 77 | } |
77 | 78 | |
78 | 79 | // уберем пустые колонки из ряда |
79 | - $this->filterRow(); | |
80 | + if ($this->keys === NULL) { | |
81 | + $this->filterRow(); | |
82 | + } | |
83 | + | |
80 | 84 | |
81 | - $this->adjustRowToSettings( ); | |
85 | + $this->adjustRowToSettings(); | |
82 | 86 | |
83 | 87 | // строка не пустая, имеем прочитанный массив значений |
84 | 88 | $this->current_row_number++; |
85 | 89 | |
86 | 90 | // для первой строки утановим ключи из заголовка |
87 | - if ( !$this->setKeysFromHeader() ) { | |
91 | + if (!$this->setKeysFromHeader()) { | |
88 | 92 | $this->setResult(); |
89 | 93 | } |
90 | 94 | |
91 | 95 | |
92 | 96 | // если у нас установлен лимит, при его достижении прекращаем парсинг |
93 | - if ( $this->isLastLine() ) | |
97 | + if ($this->isLastLine()) | |
94 | 98 | break; |
95 | 99 | |
96 | 100 | // обнуляем счетчик, так как считаюся пустые строки ПОДРЯД |
... | ... | @@ -99,6 +103,7 @@ abstract class TableParser extends Parser { |
99 | 103 | } |
100 | 104 | |
101 | 105 | } |
106 | + | |
102 | 107 | /** |
103 | 108 | * определяет первую значимую строку, |
104 | 109 | * считывается файл пока в нем не встретится строка с непустыми колонками |
... | ... | @@ -107,12 +112,12 @@ abstract class TableParser extends Parser { |
107 | 112 | */ |
108 | 113 | protected function shiftToFirstValuableLine() |
109 | 114 | { |
110 | - do { | |
115 | + do { | |
111 | 116 | |
112 | 117 | $this->current_row_number++; |
113 | 118 | $this->readRow(); |
114 | 119 | |
115 | - } while( $this->isEmptyRow() ); | |
120 | + } while ($this->isEmptyRow()); | |
116 | 121 | |
117 | 122 | // @todo - сделать опционально |
118 | 123 | // код для того что бы парсить первую строку, закомментировано как предполагается что первая значимая строка это заголовок |
... | ... | @@ -123,59 +128,76 @@ abstract class TableParser extends Parser { |
123 | 128 | /** |
124 | 129 | * @return array - одномерный массив результата парсинга строки |
125 | 130 | */ |
126 | - protected function adjustRowToSettings( ) | |
131 | + protected function adjustRowToSettings() | |
127 | 132 | { |
128 | 133 | |
129 | - // если есть заголовок, то перед конвертацией его нужно назначить | |
130 | - if ( $this->keys !== NULL ) { | |
131 | - | |
132 | - if (count($this->keys) !== count($this->row)) { | |
133 | - throw new \Exception("Ошибка парсинга файла в строке # {$this->current_row_number}. | |
134 | - Не соответсвие числа ключевых колонок (заголовка) - числу колонок с данными"); | |
135 | - } | |
136 | - | |
137 | - $this->row = array_combine($this->keys, $this->row); | |
138 | - } | |
134 | + // если есть заголовок, то перед конвертацией его нужно назначить | |
135 | + if ($this->keys !== NULL) { | |
136 | + // adjust row to keys | |
137 | + $this->adjustRowToKeys(); | |
138 | + // назначим заголовок | |
139 | + $this->row = array_combine($this->keys, $this->row); | |
140 | + } | |
139 | 141 | |
140 | - // попытаемся конвертировать прочитанные значения согласно конфигурации котнвертера значений | |
141 | - $this->row = $this->convert($this->row); | |
142 | + // попытаемся конвертировать прочитанные значения согласно конфигурации котнвертера значений | |
143 | + $this->row = $this->convert($this->row); | |
142 | 144 | |
143 | - // обрежем массив к первой значимой колонке | |
144 | - if ( $this->first_column ) { | |
145 | + // обрежем массив к первой значимой колонке | |
146 | + if ($this->first_column) { | |
145 | 147 | |
146 | - $this->row = array_slice($this->row, $this->first_column); | |
148 | + $this->row = array_slice($this->row, $this->first_column); | |
147 | 149 | |
148 | - } | |
150 | + } | |
149 | 151 | |
150 | 152 | } |
151 | 153 | |
152 | - protected function setKeysFromHeader(){ | |
153 | - if ( $this->has_header_row ) { | |
154 | + protected function setKeysFromHeader() | |
155 | + { | |
156 | + if ($this->has_header_row) { | |
154 | 157 | // в файле есть заголовок, но он еще не назначен - назначим |
155 | 158 | if ($this->keys === NULL) { |
156 | - $this->keys = array_values( $this->row ); | |
159 | + $this->keys = array_values($this->row); | |
157 | 160 | return true; |
158 | 161 | } |
159 | 162 | } |
160 | 163 | return false; |
161 | 164 | } |
162 | 165 | |
163 | - protected function filterRow(){ | |
166 | + protected function filterRow() | |
167 | + { | |
164 | 168 | // если есть заголовок - все значения нужны, не фильтруем |
165 | - if ( $this->has_header_row || !is_array( $this->row ) ) { | |
169 | + if ($this->has_header_row || !is_array($this->row)) { | |
166 | 170 | return; |
167 | 171 | } |
168 | - $this->row = array_filter( $this->row, function($val){ | |
172 | + $this->row = array_filter($this->row, function ($val) { | |
169 | 173 | return !$this->isEmptyColumn($val); |
170 | 174 | }); |
171 | 175 | } |
172 | 176 | |
173 | - protected function isLastLine(){ | |
177 | + protected function isLastLine() | |
178 | + { | |
174 | 179 | |
175 | - if ( ( $this->last_line ) && ( $this->current_row_number > $this->last_line ) ) { | |
180 | + if (($this->last_line) && ($this->current_row_number > $this->last_line)) { | |
176 | 181 | return true; |
177 | 182 | } |
178 | 183 | return false; |
179 | 184 | } |
180 | 185 | |
186 | + protected function adjustRowToKeys() | |
187 | + { | |
188 | + //уберем из ряда те колонки которых нет в ключах | |
189 | + $this->row = array_intersect_key($this->row, $this->keys); | |
190 | + | |
191 | + $keys_count = count($this->keys); | |
192 | + $column_count = count($this->row); | |
193 | + if ($keys_count != $column_count) { | |
194 | + // найдем колонки которых нет в ряде но есть ключах | |
195 | + $arr_diff = array_diff_key($this->keys, $this->row); | |
196 | + foreach ($arr_diff as $key => $value) { | |
197 | + // колонки которых нет в ряде но есть ключах, добавим их с пустым значением | |
198 | + $this->row[$key] = ''; | |
199 | + } | |
200 | + } | |
201 | + } | |
202 | + | |
181 | 203 | } |
182 | 204 | \ No newline at end of file | ... | ... |