Commit 93e3999476df72442edb1b6d7e5f80b40ed1cb0e

Authored by Mihail
1 parent 2edfb901

fixed parser and converter for console needs

backend/components/parsers/CustomCsvParser.php
@@ -9,6 +9,8 @@ @@ -9,6 +9,8 @@
9 namespace backend\components\parsers; 9 namespace backend\components\parsers;
10 10
11 11
  12 +use common\components\CustomVarDamp;
  13 +
12 class CustomCsvParser extends \yii\multiparser\CsvParser { 14 class CustomCsvParser extends \yii\multiparser\CsvParser {
13 15
14 public $last_line = 10; 16 public $last_line = 10;
@@ -33,9 +35,8 @@ class CustomCsvParser extends \yii\multiparser\CsvParser { @@ -33,9 +35,8 @@ class CustomCsvParser extends \yii\multiparser\CsvParser {
33 */ 35 */
34 protected function convert($arr) 36 protected function convert($arr)
35 { 37 {
36 - $result = \Yii::$app->multiparser->convertByConfiguration( $arr, $this->converter_conf );  
37 -  
38 - return $result; 38 + $arr = \Yii::$app->multiparser->convertByConfiguration($arr, $this->converter_conf);
  39 + return $arr;
39 40
40 } 41 }
41 42
backend/components/parsers/config.php
@@ -21,7 +21,9 @@ @@ -21,7 +21,9 @@
21 'console' => 21 'console' =>
22 ['class' => 'backend\components\parsers\CustomCsvParser', 22 ['class' => 'backend\components\parsers\CustomCsvParser',
23 'auto_detect_first_line' => true, 23 'auto_detect_first_line' => true,
  24 + 'hasHeaderRow' => true,
24 'converter_conf' => ['class' => ' backend\components\parsers\CustomConverter', 25 'converter_conf' => ['class' => ' backend\components\parsers\CustomConverter',
  26 + 'hasKey' => 1,
25 'configuration' => ["string" => 'DESCR', 27 'configuration' => ["string" => 'DESCR',
26 "float" => 'PRICE', 28 "float" => 'PRICE',
27 "integer" => ['BOX','ADD_BOX'] 29 "integer" => ['BOX','ADD_BOX']
backend/controllers/ParserController.php
@@ -16,7 +16,6 @@ use backend\models\Importers; @@ -16,7 +16,6 @@ use backend\models\Importers;
16 use yii\base\ErrorException; 16 use yii\base\ErrorException;
17 use common\components\PriceWriter; 17 use common\components\PriceWriter;
18 use common\components\CustomVarDamp; 18 use common\components\CustomVarDamp;
19 -use yii\web\ErrorAction;  
20 19
21 /** 20 /**
22 * Parser controller 21 * Parser controller
@@ -225,7 +224,7 @@ class ParserController extends BaseController @@ -225,7 +224,7 @@ class ParserController extends BaseController
225 $file_id = basename($server_file,".csv"); 224 $file_id = basename($server_file,".csv");
226 $arr_id_files[] = (int) $file_id; 225 $arr_id_files[] = (int) $file_id;
227 } 226 }
228 - Yii::$app->cache->set( 'files_to_delete',json_encode( $arr_id_files ) ); 227 + Yii::$app->cache->set( 'files_to_parse',json_encode( $arr_id_files ) );
229 $query = ImportersFiles::find()->where(['in', 'id', $arr_id_files])->orderBy(['upload_time' => SORT_DESC]); 228 $query = ImportersFiles::find()->where(['in', 'id', $arr_id_files])->orderBy(['upload_time' => SORT_DESC]);
230 229
231 $provider = new ActiveDataProvider([ 230 $provider = new ActiveDataProvider([
@@ -251,23 +250,79 @@ class ParserController extends BaseController @@ -251,23 +250,79 @@ class ParserController extends BaseController
251 unlink(Yii::getAlias('@auto_upload') . '/' . $id . '.csv' ); 250 unlink(Yii::getAlias('@auto_upload') . '/' . $id . '.csv' );
252 251
253 // удалим этот id и из кэша 252 // удалим этот id и из кэша
254 - if( $arr_id_files = Yii::$app->cache->get( 'files_to_delete' ) ){ 253 + if( $arr_id_files = Yii::$app->cache->get( 'files_to_parse' ) ){
255 $arr_id_files = json_decode($arr_id_files); 254 $arr_id_files = json_decode($arr_id_files);
256 if (isset( $arr_id_files[$id] ) ) { 255 if (isset( $arr_id_files[$id] ) ) {
257 unset( $arr_id_files[$id] ); 256 unset( $arr_id_files[$id] );
258 // положем уже обновленный массив 257 // положем уже обновленный массив
259 - Yii::$app->cache->set( 'files_to_delete',json_encode( $arr_id_files ) ); 258 + Yii::$app->cache->set( 'files_to_parse',json_encode( $arr_id_files ) );
260 } 259 }
261 } 260 }
262 // сообщим скрипту что все ОК 261 // сообщим скрипту что все ОК
263 echo 1; 262 echo 1;
264 } catch (ErrorException $e) { 263 } catch (ErrorException $e) {
265 264
266 - CustomVarDamp::dump($e->getMessage()); 265 + //CustomVarDamp::dump($e->getMessage());
  266 + throw $e;
267 267
268 } 268 }
269 } 269 }
270 } 270 }
271 271
272 } 272 }
  273 +
  274 +
  275 +
  276 +
  277 + public function actionParse ()
  278 + {
  279 +// $comand = "/usr/bin/php -f ".Yii::getAlias('@console') ."/Controllers/ParserController.php";
  280 +// exec($comand);
  281 + if( $arr_id_files = Yii::$app->cache->get( 'files_to_parse' ) ) {
  282 + $arr_id_files = json_decode( $arr_id_files );
  283 + foreach ( $arr_id_files as $file_name ) {
  284 + $file_path = Yii::getAlias('@auto_upload') . '/' . $file_name . '.csv';
  285 + $config = ['record_id' => $file_name,
  286 + 'importer_id' => ImportersFiles::findOne(['id' => $file_name])->id,
  287 + 'parser_config' => ['keys' => ['DESCR', 'ARTICLE', 'BRAND', 'PRICE', 'BOX'],
  288 + 'mode' => 'console']
  289 + ];
  290 + if( $this->parseFileConsole( $file_path, $config ) ){
  291 + unlink( $file_path );
  292 + if (isset( $arr_id_files[$file_path] ) ) {
  293 + unset($arr_id_files[$file_path]);
  294 + }
  295 + } else {
  296 + // Yii::$app->log->
  297 + // не дошли до конца по этому остаки вернем в кеш
  298 + Yii::$app->cache->set( 'files_to_parse',json_encode( $arr_id_files ) );
  299 + }
  300 + }
  301 + if ( !count( $arr_id_files ) ) {
  302 + Yii::$app->cache->delete( 'files_to_parse' );
  303 + }
  304 + }
  305 +
  306 + return $this->redirect('serverFiles');
  307 + }
  308 +
  309 + protected function parseFileConsole( $file_path, $configuration ){
  310 + $parser_config = [];
  311 + if ( isset( $configuration['parser_config'] ) ) {
  312 + $parser_config = $configuration['parser_config'];
  313 + }
  314 +
  315 + $data = Yii::$app->multiparser->parse( $file_path, $parser_config );
  316 + CustomVarDamp::dumpAndDie($data);
  317 + $writer = new PriceWriter();
  318 + $writer->configuration = $configuration;
  319 + $writer->data = $data;
  320 + $writer->mode = 1; //console-режим
  321 + if ( $writer->writeDataToDB() ){
  322 + //Console::output('It is working');
  323 + return true;
  324 + }
  325 +
  326 + return false;
  327 + }
273 } 328 }
backend/views/parser/server-files.php
1 <?php 1 <?php
2 use yii\helpers\Html; 2 use yii\helpers\Html;
  3 +use yii\helpers\Url;
3 use yii\grid\GridView; 4 use yii\grid\GridView;
4 use yii\grid\SerialColumn; 5 use yii\grid\SerialColumn;
5 use yii\grid\ActionColumn; 6 use yii\grid\ActionColumn;
@@ -44,7 +45,7 @@ Pjax::begin([&#39;id&#39; =&gt; &#39;server_files_grid&#39;]); @@ -44,7 +45,7 @@ Pjax::begin([&#39;id&#39; =&gt; &#39;server_files_grid&#39;]);
44 45
45 ]] );?> 46 ]] );?>
46 47
47 - 48 + <?= Html::a('Загрузить файлы', ['parse'],['class' => 'btn btn-success']) ?>
48 49
49 </div> 50 </div>
50 <?php 51 <?php
common/components/PriceWriter.php
@@ -24,7 +24,7 @@ class PriceWriter { @@ -24,7 +24,7 @@ class PriceWriter {
24 { 24 {
25 // 1. запишем дату старта в таблицу файлов поставщика (ImportersFiles) 25 // 1. запишем дату старта в таблицу файлов поставщика (ImportersFiles)
26 // id загруженного файла получим из конфигурации 26 // id загруженного файла получим из конфигурации
27 - $files_model = ImportersFiles::findOne( $this->configuration->record_id ); 27 + $files_model = ImportersFiles::findOne( $this->configuration['record_id'] );
28 28
29 //$files_model->load(['ImportersFiles' => $this->configuration->toArray()]); 29 //$files_model->load(['ImportersFiles' => $this->configuration->toArray()]);
30 $update_date = date('Y-m-d H:i:s'); 30 $update_date = date('Y-m-d H:i:s');
@@ -61,7 +61,7 @@ class PriceWriter { @@ -61,7 +61,7 @@ class PriceWriter {
61 } 61 }
62 else{ 62 else{
63 // дополним данные значением импортера и даты обновления цены 63 // дополним данные значением импортера и даты обновления цены
64 - $this->data = \Yii::$app->multiparser->addColumns($this->data, ['IMPORT_ID' => $this->configuration->importer_id, 'timestamp' => $update_date]); 64 + $this->data = \Yii::$app->multiparser->addColumns($this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date]);
65 65
66 try { 66 try {
67 //@todo add transaction 67 //@todo add transaction
console/controllers/ParserController.php
@@ -6,19 +6,59 @@ @@ -6,19 +6,59 @@
6 * Time: 14:38 6 * Time: 14:38
7 */ 7 */
8 use yii\console\Controller; 8 use yii\console\Controller;
  9 +use yii\helpers\Console;
  10 +use common\components\PriceWriter;
  11 +use backend\models\ImportersFiles;
9 12
10 class ParserController extends Controller{ 13 class ParserController extends Controller{
11 public function actionParseCSV () 14 public function actionParseCSV ()
12 { 15 {
13 - 16 + \common\components\CustomVarDamp::dumpAndDie(45);
  17 + if( $arr_id_files = Yii::$app->cache->get( 'files_to_parse' ) ) {
  18 + $arr_id_files = json_decode( $arr_id_files );
  19 + foreach ( $arr_id_files as $file_name ) {
  20 + $file_path = Yii::getAlias('@auto_upload') . '/' . $file_name . '.csv';
  21 + $config = ['record_id' => $file_name,
  22 + 'importer_id' => ImportersFiles::findOne(['id' => $file_name])->id,
  23 + 'parser_config' => ['keys' => ['DESCR', 'ARTICLE', 'BRAND', 'PRICE', 'BOX']]
  24 + ];
  25 + if( $this->parseFileConsole( $file_path, $config ) ){
  26 + unlink( $file_path );
  27 + if (isset( $arr_id_files[$file_path] ) ) {
  28 + unset($arr_id_files[$file_path]);
  29 + }
  30 + } else {
  31 + // Yii::$app->log->
  32 + // не дошли до конца по этому остаки вернем в кеш
  33 + Yii::$app->cache->set( 'files_to_parse',json_encode( $arr_id_files ) );
  34 + }
  35 + }
  36 + if ( !count( $arr_id_files ) ) {
  37 + Yii::$app->cache->delete( 'files_to_parse' );
  38 + }
  39 + }
14 } 40 }
15 public function actionParseXML () 41 public function actionParseXML ()
16 { 42 {
17 43
18 } 44 }
19 - protected function parseFileConsole( $file_path ){ 45 + protected function parseFileConsole( $file_path, $configuration ){
  46 + $parser_config = [];
  47 + if ( isset( $configuration['parser_config'] ) ) {
  48 + $parser_config = $configuration['parser_config'];
  49 + }
  50 +
  51 + $data = Yii::$app->multiparser->parse( $file_path, $parser_config );
20 52
21 - $data = Yii::$app->multiparser->parse( $file_path ); 53 + $writer = new PriceWriter();
  54 + $writer->configuration = $configuration;
  55 + $writer->data = $data;
  56 + $writer->mode = 1; //console-режим
  57 + if ( $writer->writeDataToDB() ){
  58 + Console::output('It is working');
  59 + return true;
  60 + }
22 61
  62 + return false;
23 } 63 }
24 } 64 }
25 \ No newline at end of file 65 \ No newline at end of file
vendor/yiisoft/multiparser/Converter.php
@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 */ 7 */
8 8
9 namespace yii\multiparser; 9 namespace yii\multiparser;
  10 +use common\components\CustomVarDamp;
10 use yii\base\Behavior; 11 use yii\base\Behavior;
11 12
12 // класс который содержит преобразователи значений (фильтры) используемые при парсинге 13 // класс который содержит преобразователи значений (фильтры) используемые при парсинге
@@ -19,7 +20,6 @@ class Converter extends Behavior @@ -19,7 +20,6 @@ class Converter extends Behavior
19 20
20 public static function convertToFloat($value) 21 public static function convertToFloat($value)
21 { 22 {
22 - echo 1;  
23 if ($value == '') { 23 if ($value == '') {
24 $value = 0; 24 $value = 0;
25 } 25 }
@@ -51,8 +51,6 @@ class Converter extends Behavior @@ -51,8 +51,6 @@ class Converter extends Behavior
51 51
52 public static function convertToString($value) 52 public static function convertToString($value)
53 { 53 {
54 -  
55 -  
56 $res = ''; 54 $res = '';
57 if (is_array($value)) { 55 if (is_array($value)) {
58 56
@@ -101,7 +99,7 @@ class Converter extends Behavior @@ -101,7 +99,7 @@ class Converter extends Behavior
101 public static function convertByConfiguration( $arr, $configuration ) 99 public static function convertByConfiguration( $arr, $configuration )
102 { 100 {
103 $result = $arr; 101 $result = $arr;
104 - //\common\components\CustomVarDamp::dumpAndDie($configuration); 102 + // \common\components\CustomVarDamp::dumpAndDie( $result );
105 $hasKey = isset( $configuration['hasKey'] ); 103 $hasKey = isset( $configuration['hasKey'] );
106 foreach ( $configuration['configuration'] as $key => $value ) { 104 foreach ( $configuration['configuration'] as $key => $value ) {
107 105
@@ -111,7 +109,7 @@ class Converter extends Behavior @@ -111,7 +109,7 @@ class Converter extends Behavior
111 foreach ($value as $sub_value) { 109 foreach ($value as $sub_value) {
112 if (isset($arr[$sub_value])) { 110 if (isset($arr[$sub_value])) {
113 // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле 111 // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле
114 - $result[$arr[$sub_value]] = self::$key( $arr[$sub_value] ); 112 + $result[$sub_value] = self::$key( $arr[$sub_value] );
115 } 113 }
116 114
117 } 115 }
@@ -119,7 +117,7 @@ class Converter extends Behavior @@ -119,7 +117,7 @@ class Converter extends Behavior
119 117
120 if (isset($arr[$value])) { 118 if (isset($arr[$value])) {
121 // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле 119 // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле
122 - $result[$arr[$value]] = self::$key( $arr[$value] ); 120 + $result[$value] = self::$key( $arr[$value] );
123 } 121 }
124 122
125 } 123 }
vendor/yiisoft/multiparser/CsvParser.php
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 3
4 */ 4 */
5 namespace yii\multiparser; 5 namespace yii\multiparser;
  6 +use common\components\CustomVarDamp;
6 7
7 8
8 /** 9 /**
@@ -97,7 +98,7 @@ class CsvParser implements ParserInterface @@ -97,7 +98,7 @@ class CsvParser implements ParserInterface
97 98
98 while (!$finish) { 99 while (!$finish) {
99 $j = 0; 100 $j = 0;
100 - $row = $this->readRow(); 101 + $row = $this->file->fgetcsv();;
101 if ($row === false) { 102 if ($row === false) {
102 continue; 103 continue;
103 } 104 }
@@ -129,7 +130,7 @@ class CsvParser implements ParserInterface @@ -129,7 +130,7 @@ class CsvParser implements ParserInterface
129 $empty_lines = 0; 130 $empty_lines = 0;
130 while ( $empty_lines < 3 ) { 131 while ( $empty_lines < 3 ) {
131 // прочтем строку из файла. Если там есть значения - то в ней массив, иначе - false 132 // прочтем строку из файла. Если там есть значения - то в ней массив, иначе - false
132 - $row = $this->readRow(); 133 + $row = $this->readRow( $current_line );
133 134
134 if ($row === false) { 135 if ($row === false) {
135 //счетчик пустых строк 136 //счетчик пустых строк
@@ -139,19 +140,10 @@ class CsvParser implements ParserInterface @@ -139,19 +140,10 @@ class CsvParser implements ParserInterface
139 // строка не пустая, имеем прочитанный массив значений 140 // строка не пустая, имеем прочитанный массив значений
140 $current_line++; 141 $current_line++;
141 if ($this->hasHeaderRow) { 142 if ($this->hasHeaderRow) {
  143 + // в файле есть заголовок, но он еще не назначен, назначим
142 if ($this->keys === NULL) { 144 if ($this->keys === NULL) {
143 $this->keys = array_values($row); 145 $this->keys = array_values($row);
144 - } else {  
145 -  
146 - if (count($this->keys) !== count($row)) {  
147 -//  
148 - throw new \ErrorException("Invalid columns detected on line # {$current_line}", 0, 1, $this->file->getBasename(), $current_line);  
149 - }  
150 -  
151 - $return[] = array_combine($this->keys, $row);  
152 } 146 }
153 - } else {  
154 - $return[] = $row;  
155 } 147 }
156 // если у нас установлен лимит, при его достижении прекращаем парсинг 148 // если у нас установлен лимит, при его достижении прекращаем парсинг
157 if (($this->last_line) && ($current_line > $this->last_line)) { 149 if (($this->last_line) && ($current_line > $this->last_line)) {
@@ -159,6 +151,8 @@ class CsvParser implements ParserInterface @@ -159,6 +151,8 @@ class CsvParser implements ParserInterface
159 } 151 }
160 // обнуляем счетчик, так как считаюся пустые строки ПОДРЯД 152 // обнуляем счетчик, так как считаюся пустые строки ПОДРЯД
161 $empty_lines = 0; 153 $empty_lines = 0;
  154 +
  155 + $return[] = $row;
162 } 156 }
163 157
164 $this->closeHandler(); 158 $this->closeHandler();
@@ -174,16 +168,24 @@ class CsvParser implements ParserInterface @@ -174,16 +168,24 @@ class CsvParser implements ParserInterface
174 /** 168 /**
175 * @return array - одномерный массив результата парсинга строки 169 * @return array - одномерный массив результата парсинга строки
176 */ 170 */
177 - protected function readRow() 171 + protected function readRow( $current_line )
178 { 172 {
179 -  
180 $row = $this->file->fgetcsv(); 173 $row = $this->file->fgetcsv();
181 -  
182 if (is_array($row)) { 174 if (is_array($row)) {
183 - // попытаемся конвертировать прочитанные занчения согдасно конфигурации котнвертера значений 175 + // если есть заголовок, то перед конвертацией его нужно назначить
  176 + if ($this->hasHeaderRow && $this->keys !== NULL) {
  177 +
  178 + if (count($this->keys) !== count($row)) {
  179 +//
  180 + throw new \ErrorException("Ошибка парсинга файла в строке # {$current_line}. Не соответсвие числа ключевых колонок (заголовка) - числу колонок с данными", 0, 1, $this->file->getBasename(), $current_line);
  181 + }
  182 +
  183 + $row = array_combine($this->keys, $row);
  184 + }
  185 + // попытаемся конвертировать прочитанные значения согласно конфигурации котнвертера значений
184 $row = $this->convert($row); 186 $row = $this->convert($row);
185 - // \common\components\CustomVarDamp::dump($row);  
186 - if ($this->first_column) { 187 + // обрежем массив к первой значимой колонке
  188 + if ( $this->first_column ) {
187 189
188 $row = array_slice($row, $this->first_column); 190 $row = array_slice($row, $this->first_column);
189 191
vendor/yiisoft/multiparser/YiiMultiparser.php
@@ -39,14 +39,5 @@ public $configuration; @@ -39,14 +39,5 @@ public $configuration;
39 39
40 } 40 }
41 41
42 - public function init()  
43 - {  
44 - if( isset($this->configuration['glob']) && isset($this->configuration['glob']['ini'])){  
45 - foreach ($this->configuration['glob']['ini'] as $ini_setting => $ini_setting_value) {  
46 - ini_set( $ini_setting, $ini_setting_value );  
47 - }  
48 - }  
49 -  
50 - }  
51 42
52 } 43 }
53 \ No newline at end of file 44 \ No newline at end of file