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 9 namespace backend\components\parsers;
10 10  
11 11  
  12 +use common\components\CustomVarDamp;
  13 +
12 14 class CustomCsvParser extends \yii\multiparser\CsvParser {
13 15  
14 16 public $last_line = 10;
... ... @@ -33,9 +35,8 @@ class CustomCsvParser extends \yii\multiparser\CsvParser {
33 35 */
34 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 21 'console' =>
22 22 ['class' => 'backend\components\parsers\CustomCsvParser',
23 23 'auto_detect_first_line' => true,
  24 + 'hasHeaderRow' => true,
24 25 'converter_conf' => ['class' => ' backend\components\parsers\CustomConverter',
  26 + 'hasKey' => 1,
25 27 'configuration' => ["string" => 'DESCR',
26 28 "float" => 'PRICE',
27 29 "integer" => ['BOX','ADD_BOX']
... ...
backend/controllers/ParserController.php
... ... @@ -16,7 +16,6 @@ use backend\models\Importers;
16 16 use yii\base\ErrorException;
17 17 use common\components\PriceWriter;
18 18 use common\components\CustomVarDamp;
19   -use yii\web\ErrorAction;
20 19  
21 20 /**
22 21 * Parser controller
... ... @@ -225,7 +224,7 @@ class ParserController extends BaseController
225 224 $file_id = basename($server_file,".csv");
226 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 228 $query = ImportersFiles::find()->where(['in', 'id', $arr_id_files])->orderBy(['upload_time' => SORT_DESC]);
230 229  
231 230 $provider = new ActiveDataProvider([
... ... @@ -251,23 +250,79 @@ class ParserController extends BaseController
251 250 unlink(Yii::getAlias('@auto_upload') . '/' . $id . '.csv' );
252 251  
253 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 254 $arr_id_files = json_decode($arr_id_files);
256 255 if (isset( $arr_id_files[$id] ) ) {
257 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 262 echo 1;
264 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 1 <?php
2 2 use yii\helpers\Html;
  3 +use yii\helpers\Url;
3 4 use yii\grid\GridView;
4 5 use yii\grid\SerialColumn;
5 6 use yii\grid\ActionColumn;
... ... @@ -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 50 </div>
50 51 <?php
... ...
common/components/PriceWriter.php
... ... @@ -24,7 +24,7 @@ class PriceWriter {
24 24 {
25 25 // 1. запишем дату старта в таблицу файлов поставщика (ImportersFiles)
26 26 // id загруженного файла получим из конфигурации
27   - $files_model = ImportersFiles::findOne( $this->configuration->record_id );
  27 + $files_model = ImportersFiles::findOne( $this->configuration['record_id'] );
28 28  
29 29 //$files_model->load(['ImportersFiles' => $this->configuration->toArray()]);
30 30 $update_date = date('Y-m-d H:i:s');
... ... @@ -61,7 +61,7 @@ class PriceWriter {
61 61 }
62 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 66 try {
67 67 //@todo add transaction
... ...
console/controllers/ParserController.php
... ... @@ -6,19 +6,59 @@
6 6 * Time: 14:38
7 7 */
8 8 use yii\console\Controller;
  9 +use yii\helpers\Console;
  10 +use common\components\PriceWriter;
  11 +use backend\models\ImportersFiles;
9 12  
10 13 class ParserController extends Controller{
11 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 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 65 \ No newline at end of file
... ...
vendor/yiisoft/multiparser/Converter.php
... ... @@ -7,6 +7,7 @@
7 7 */
8 8  
9 9 namespace yii\multiparser;
  10 +use common\components\CustomVarDamp;
10 11 use yii\base\Behavior;
11 12  
12 13 // класс который содержит преобразователи значений (фильтры) используемые при парсинге
... ... @@ -19,7 +20,6 @@ class Converter extends Behavior
19 20  
20 21 public static function convertToFloat($value)
21 22 {
22   - echo 1;
23 23 if ($value == '') {
24 24 $value = 0;
25 25 }
... ... @@ -51,8 +51,6 @@ class Converter extends Behavior
51 51  
52 52 public static function convertToString($value)
53 53 {
54   -
55   -
56 54 $res = '';
57 55 if (is_array($value)) {
58 56  
... ... @@ -101,7 +99,7 @@ class Converter extends Behavior
101 99 public static function convertByConfiguration( $arr, $configuration )
102 100 {
103 101 $result = $arr;
104   - //\common\components\CustomVarDamp::dumpAndDie($configuration);
  102 + // \common\components\CustomVarDamp::dumpAndDie( $result );
105 103 $hasKey = isset( $configuration['hasKey'] );
106 104 foreach ( $configuration['configuration'] as $key => $value ) {
107 105  
... ... @@ -111,7 +109,7 @@ class Converter extends Behavior
111 109 foreach ($value as $sub_value) {
112 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 117  
120 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 3  
4 4 */
5 5 namespace yii\multiparser;
  6 +use common\components\CustomVarDamp;
6 7  
7 8  
8 9 /**
... ... @@ -97,7 +98,7 @@ class CsvParser implements ParserInterface
97 98  
98 99 while (!$finish) {
99 100 $j = 0;
100   - $row = $this->readRow();
  101 + $row = $this->file->fgetcsv();;
101 102 if ($row === false) {
102 103 continue;
103 104 }
... ... @@ -129,7 +130,7 @@ class CsvParser implements ParserInterface
129 130 $empty_lines = 0;
130 131 while ( $empty_lines < 3 ) {
131 132 // прочтем строку из файла. Если там есть значения - то в ней массив, иначе - false
132   - $row = $this->readRow();
  133 + $row = $this->readRow( $current_line );
133 134  
134 135 if ($row === false) {
135 136 //счетчик пустых строк
... ... @@ -139,19 +140,10 @@ class CsvParser implements ParserInterface
139 140 // строка не пустая, имеем прочитанный массив значений
140 141 $current_line++;
141 142 if ($this->hasHeaderRow) {
  143 + // в файле есть заголовок, но он еще не назначен, назначим
142 144 if ($this->keys === NULL) {
143 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 149 if (($this->last_line) && ($current_line > $this->last_line)) {
... ... @@ -159,6 +151,8 @@ class CsvParser implements ParserInterface
159 151 }
160 152 // обнуляем счетчик, так как считаюся пустые строки ПОДРЯД
161 153 $empty_lines = 0;
  154 +
  155 + $return[] = $row;
162 156 }
163 157  
164 158 $this->closeHandler();
... ... @@ -174,16 +168,24 @@ class CsvParser implements ParserInterface
174 168 /**
175 169 * @return array - одномерный массив результата парсинга строки
176 170 */
177   - protected function readRow()
  171 + protected function readRow( $current_line )
178 172 {
179   -
180 173 $row = $this->file->fgetcsv();
181   -
182 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 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 190 $row = array_slice($row, $this->first_column);
189 191  
... ...
vendor/yiisoft/multiparser/YiiMultiparser.php
... ... @@ -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 44 \ No newline at end of file
... ...