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 | ... | ... |