From 40ff24a1aa0f48138c496b2cc58fa0c2b5b69a2a Mon Sep 17 00:00:00 2001 From: Mihail Date: Fri, 4 Sep 2015 17:40:26 +0300 Subject: [PATCH] refactor CsvParser, add CustomCsvParser --- backend/components/parsers/CsvParser.php | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------ backend/components/parsers/CustomCsvParser.php | 28 ++++++++++++++++++++++++++++ backend/components/parsers/Encoder.php | 7 ++++--- backend/components/parsers/ParserHandler.php | 14 +++++--------- 4 files changed, 95 insertions(+), 72 deletions(-) create mode 100644 backend/components/parsers/CustomCsvParser.php diff --git a/backend/components/parsers/CsvParser.php b/backend/components/parsers/CsvParser.php index 1ea01c6..d396772 100644 --- a/backend/components/parsers/CsvParser.php +++ b/backend/components/parsers/CsvParser.php @@ -1,11 +1,8 @@ file->setCsvControl($this->delimiter); $this->file->setFlags(\SplFileObject::READ_CSV); $this->file->setFlags(\SplFileObject::SKIP_EMPTY); -// $this->file->setFlags(\SplFileObject::READ_AHEAD); - - if ($this->auto_detect_start_position) { - $this->first_line = $this->detectStartPosition(); + if ($this->auto_detect_first_line) { + $this->shiftToFirstValuableLine(); } - // CustomVarDamp::dumpAndDie($this); -// echo $this->file->key(); -// $this->file->seek($this->first_line + 1); -// echo $this->file->key(); - - } - - protected function detectStartPosition() + /** + * определяет первую значимую строку, + * считывается файл пока в нем не встретится строка с непустыми колонками + * в количестве указанном в атрибуте min_column_quantity + * в результате выполнения курсор ресурса будет находится на последней незначимой строке + */ + protected function shiftToFirstValuableLine() { - $first_line = 0; - $find = false; - while (!$find) { + $finish = false; + + while (!$finish) { $j = 0; $row = $this->readRow(); - if ($row === false) { continue; } - $first_line++; for ($i = 1; $i <= count($row); $i++) { if ($row[$i - 1] <> '') { @@ -82,30 +85,25 @@ class CsvParser } if ($j >= $this->min_column_quantity) { - $find = true; - break; + break 2; } } } - - return $first_line; - } /** - * @return array - * @throws InvalidFileException + * @return array - итоговый двумерный массив с результатом парсинга + * метод считывает с открытого файла данные построчно */ public function read() { - // @todo add comments $return = []; - //CustomVarDamp::dump(debug_print_backtrace(1,2)); - $line = 0; + + $current_line = 0; $this->keys = NULL; - CustomVarDamp::dump($this->file->key()); + while (($row = $this->readRow()) !== FALSE) { - $line++; + $current_line++; if ($this->hasHeaderRow) { if ($this->keys === NULL) { @@ -114,25 +112,25 @@ class CsvParser if (count($this->keys) !== count($row)) { // - Yii::warning("Invalid columns detected on line #$line ."); + Yii::warning("Invalid columns detected on line #$current_line ."); return $return; } $return[] = array_combine($this->keys, $row); } - } else { + } + else + { $return[] = $row; } - if(($this->last_line) && ($line > $this->last_line)){ -// CustomVarDamp::dump($this->last_line); -// CustomVarDamp::dump($line); + // если у нас установлен лимит, при его достижении прекращаем парсинг + if (($this->last_line) && ($current_line > $this->last_line)) { break; } } $this->closeHandler(); - //CustomVarDamp::dumpAndDie($return); return $return; } @@ -142,20 +140,20 @@ class CsvParser $this->file = NULL; } + /** + * @return array - одномерный массив результата парсинга строки + */ protected function readRow() - // @todo add comments { $row = $this->file->fgetcsv(); - // - if (is_array($row)) { - // $row = array_slice( $row, $this->first_column ); - $row = Encoder::encodeArray($this->in_charset, $this->out_charset, $row); + if (is_array($row) && $this->first_column) { + + $row = array_slice($row, $this->first_column); + } if (is_null($row)) $row = false; -// if ($this->keys !== NULL) -// @$clear_arr[3] = ValueFilter::pricefilter($clear_arr[3]);{}{}{} return $row; diff --git a/backend/components/parsers/CustomCsvParser.php b/backend/components/parsers/CustomCsvParser.php new file mode 100644 index 0000000..18df388 --- /dev/null +++ b/backend/components/parsers/CustomCsvParser.php @@ -0,0 +1,28 @@ +extension = 'csv'){ - $first_line = isset( $this->options->first_line )? $this->options->first_line : 0; - $first_column = isset( $this->options->first_column )? $this->options->first_column : 0; $csvParser = Yii::createObject([ - 'class' => 'backend\components\parsers\CsvParser', + 'class' => 'backend\components\parsers\CustomCsvParser', 'file' => $this->fileObject, - 'auto_detect_start_position' => true, + 'auto_detect_first_line' => true, ]); - //CustomVarDamp::dumpAndDie($csvParser); - // $csvParser = new CsvParser( ); - $csvParser->setup( ); -// CustomVarDamp::dumpAndDie($data); - return $csvParser->read();;// + $csvParser->setup(); + + return $csvParser->read(); }; } } -- libgit2 0.21.4