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,7 +11,8 @@ namespace yii\multiparser; | ||
| 11 | 11 | ||
| 12 | use common\components\CustomVarDamp; | 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,7 +40,7 @@ abstract class TableParser extends Parser { | ||
| 39 | * используется при автоопределении первой строки*/ | 40 | * используется при автоопределении первой строки*/ |
| 40 | public $min_column_quantity = 5; | 41 | public $min_column_quantity = 5; |
| 41 | /** @var int - количество пустых строк, что бы определить конец файла, | 42 | /** @var int - количество пустых строк, что бы определить конец файла, |
| 42 | - такое количеество подряд пустых строк считается концом файла*/ | 43 | + * такое количеество подряд пустых строк считается концом файла*/ |
| 43 | public $empty_lines_quantity = 3; | 44 | public $empty_lines_quantity = 3; |
| 44 | 45 | ||
| 45 | 46 | ||
| @@ -64,11 +65,11 @@ abstract class TableParser extends Parser { | @@ -64,11 +65,11 @@ abstract class TableParser extends Parser { | ||
| 64 | 65 | ||
| 65 | // будем считать количество пустых строк подряд - при достижении $empty_lines_quantity - считаем что это конец файла и выходим | 66 | // будем считать количество пустых строк подряд - при достижении $empty_lines_quantity - считаем что это конец файла и выходим |
| 66 | $empty_lines = 0; | 67 | $empty_lines = 0; |
| 67 | - while ( $empty_lines < $this->empty_lines_quantity ) { | 68 | + while ($empty_lines < $this->empty_lines_quantity) { |
| 68 | // прочтем строку из файла | 69 | // прочтем строку из файла |
| 69 | $this->readRow(); | 70 | $this->readRow(); |
| 70 | 71 | ||
| 71 | - if ( $this->isEmptyRow() ) { | 72 | + if ($this->isEmptyRow()) { |
| 72 | //счетчик пустых строк | 73 | //счетчик пустых строк |
| 73 | //CustomVarDamp::dump($this->current_row_number); | 74 | //CustomVarDamp::dump($this->current_row_number); |
| 74 | $empty_lines++; | 75 | $empty_lines++; |
| @@ -76,21 +77,24 @@ abstract class TableParser extends Parser { | @@ -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 | $this->current_row_number++; | 88 | $this->current_row_number++; |
| 85 | 89 | ||
| 86 | // для первой строки утановим ключи из заголовка | 90 | // для первой строки утановим ключи из заголовка |
| 87 | - if ( !$this->setKeysFromHeader() ) { | 91 | + if (!$this->setKeysFromHeader()) { |
| 88 | $this->setResult(); | 92 | $this->setResult(); |
| 89 | } | 93 | } |
| 90 | 94 | ||
| 91 | 95 | ||
| 92 | // если у нас установлен лимит, при его достижении прекращаем парсинг | 96 | // если у нас установлен лимит, при его достижении прекращаем парсинг |
| 93 | - if ( $this->isLastLine() ) | 97 | + if ($this->isLastLine()) |
| 94 | break; | 98 | break; |
| 95 | 99 | ||
| 96 | // обнуляем счетчик, так как считаюся пустые строки ПОДРЯД | 100 | // обнуляем счетчик, так как считаюся пустые строки ПОДРЯД |
| @@ -99,6 +103,7 @@ abstract class TableParser extends Parser { | @@ -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,12 +112,12 @@ abstract class TableParser extends Parser { | ||
| 107 | */ | 112 | */ |
| 108 | protected function shiftToFirstValuableLine() | 113 | protected function shiftToFirstValuableLine() |
| 109 | { | 114 | { |
| 110 | - do { | 115 | + do { |
| 111 | 116 | ||
| 112 | $this->current_row_number++; | 117 | $this->current_row_number++; |
| 113 | $this->readRow(); | 118 | $this->readRow(); |
| 114 | 119 | ||
| 115 | - } while( $this->isEmptyRow() ); | 120 | + } while ($this->isEmptyRow()); |
| 116 | 121 | ||
| 117 | // @todo - сделать опционально | 122 | // @todo - сделать опционально |
| 118 | // код для того что бы парсить первую строку, закомментировано как предполагается что первая значимая строка это заголовок | 123 | // код для того что бы парсить первую строку, закомментировано как предполагается что первая значимая строка это заголовок |
| @@ -123,59 +128,76 @@ abstract class TableParser extends Parser { | @@ -123,59 +128,76 @@ abstract class TableParser extends Parser { | ||
| 123 | /** | 128 | /** |
| 124 | * @return array - одномерный массив результата парсинга строки | 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 | if ($this->keys === NULL) { | 158 | if ($this->keys === NULL) { |
| 156 | - $this->keys = array_values( $this->row ); | 159 | + $this->keys = array_values($this->row); |
| 157 | return true; | 160 | return true; |
| 158 | } | 161 | } |
| 159 | } | 162 | } |
| 160 | return false; | 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 | return; | 170 | return; |
| 167 | } | 171 | } |
| 168 | - $this->row = array_filter( $this->row, function($val){ | 172 | + $this->row = array_filter($this->row, function ($val) { |
| 169 | return !$this->isEmptyColumn($val); | 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 | return true; | 181 | return true; |
| 177 | } | 182 | } |
| 178 | return false; | 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 | \ No newline at end of file | 204 | \ No newline at end of file |