Blame view

backend/controllers/ParserController.php 14 KB
3cf42f5c   Mihail   init commit - bas...
1
2
3
  <?php
  namespace backend\controllers;
  
4f3f27e8   Mihail   temp commit - tes...
4
5
6
  use common\components\archives\ArchiveCreator;
  use common\components\mail\ImapMailReader;
  use common\components\mail\MailAttachmentsSaver;
1cc27986   Mihail   merge with server
7
  use common\components\parsers\MailParser;
3cf42f5c   Mihail   init commit - bas...
8
  use Yii;
dd60c760   Mihail   add menu and chec...
9
  use yii\data\ActiveDataProvider;
3cf42f5c   Mihail   init commit - bas...
10
  use yii\filters\AccessControl;
693c46cb   Mihail   add base classes ...
11
  use backend\components\base\BaseController;
3cf42f5c   Mihail   init commit - bas...
12
  use yii\filters\VerbFilter;
b13b1c83   Mihail   final version par...
13
  use backend\models\UploadFileParsingForm;
3cf42f5c   Mihail   init commit - bas...
14
  use yii\web\UploadedFile;
fcd9278e   Mihail   parser csv v1
15
  use yii\data\ArrayDataProvider;
74072a2a   Mihail   add first version...
16
  use yii\multiparser\DynamicFormHelper;
1967135b   Mihail   adapt project to ...
17
18
  use backend\models\ImportersFiles;
  use backend\models\Importers;
8894c93a   Mihail   add Importers fil...
19
  use yii\base\ErrorException;
2edfb901   Mihail   add PriceWriter a...
20
  use common\components\PriceWriter;
e774f057   Mihail   work with custome...
21
  use common\components\CustomVarDamp;
6215a30d   Mihail   add converter int...
22
  use common\components\CustomArrayHelper;
3cf42f5c   Mihail   init commit - bas...
23
24
  
  /**
b13b1c83   Mihail   final version par...
25
   * Parser controller
3cf42f5c   Mihail   init commit - bas...
26
   */
693c46cb   Mihail   add base classes ...
27
  class ParserController extends BaseController
3cf42f5c   Mihail   init commit - bas...
28
  {
500b481a   Administrator   JSON
29
      public $layout = "/column";
8894c93a   Mihail   add Importers fil...
30
  
3cf42f5c   Mihail   init commit - bas...
31
32
33
34
35
36
37
38
39
40
      /**
       * @inheritdoc
       */
      public function behaviors()
      {
          return [
              'access' => [
                  'class' => AccessControl::className(),
                  'rules' => [
                      [
3cf42f5c   Mihail   init commit - bas...
41
42
43
44
45
                          'allow' => true,
                          'roles' => ['@'],
                      ],
                  ],
              ],
e774f057   Mihail   work with custome...
46
47
48
49
50
51
  //            'verbs' => [
  //                'class' => VerbFilter::className(),
  //                'actions' => [
  //                    'logout' => ['post'],
  //                ],
  //            ],
3cf42f5c   Mihail   init commit - bas...
52
53
54
          ];
      }
  
3cf42f5c   Mihail   init commit - bas...
55
  
500b481a   Administrator   JSON
56
  
9e481998   Mihail   add auto upload a...
57
      public function actionIndex($mode = 0)
3cf42f5c   Mihail   init commit - bas...
58
      {
4f3f27e8   Mihail   temp commit - tes...
59
          $this->mailTest();
77422ce3   Mihail   edit upload form
60
          $model = new UploadFileParsingForm();
9e481998   Mihail   add auto upload a...
61
62
          // установим режим, 0 - ручная загрузка, 1 - автозагрузка
          $model->mode = $mode;
500b481a   Administrator   JSON
63
64
65
          return $this->render('index', ['model' => $model]);
      }
  
2edfb901   Mihail   add PriceWriter a...
66
67
68
69
70
71
72
      public function actionError()
      {
          $exception = Yii::$app->errorHandler->exception;
          if ($exception !== null) {
              return $this->render('error', ['message' => $exception->getMessage()]);
          }
      }
9d57a9ea   Mihail   try organize ini ...
73
  
9e481998   Mihail   add auto upload a...
74
      public function actionResults($mode = 0)
8894c93a   Mihail   add Importers fil...
75
      {
9e481998   Mihail   add auto upload a...
76
          $model = new UploadFileParsingForm(['mode' => $mode]);
474f35bf   Mihail   add DynamicFormHe...
77
          $data = [];
b13b1c83   Mihail   final version par...
78
          if ($model->load(Yii::$app->request->post())) {
3cf42f5c   Mihail   init commit - bas...
79
              $model->file = UploadedFile::getInstance($model, 'file');
9e481998   Mihail   add auto upload a...
80
              // первый проход - валидируем, сохраняем файл, ложим в кеш (для ручной загрузки) отпарсенные данные и параметры модели (потом при записи в базу данных они пригодятся)
3663f570   Mihail   draft commit
81
              if ($model->validate()) {
9e481998   Mihail   add auto upload a...
82
                  // запишем дату загрузки файла в таблицу файлов поставщика (ImportersFiles)
1967135b   Mihail   adapt project to ...
83
                  $files_model = new ImportersFiles();
9e481998   Mihail   add auto upload a...
84
                  // id поставщика получим из конфигурации
1967135b   Mihail   adapt project to ...
85
                  $files_model->load(['ImportersFiles' => $model->toArray()]);
9e481998   Mihail   add auto upload a...
86
87
88
                  try {
                      $files_model->save();
                  } catch (ErrorException  $e) {
2edfb901   Mihail   add PriceWriter a...
89
                      throw $e;
9e481998   Mihail   add auto upload a...
90
91
                  }
                  // получим id только что записанной записи - его запишем в название файла
01746976   Mihail   fix errors with w...
92
                  $model->record_id = $files_model->find()
9e481998   Mihail   add auto upload a...
93
94
95
96
97
                      ->where(['importer_id' => $files_model->importer_id])
                      ->orderBy(['id' => SORT_DESC])
                      ->one()
                      ->id;
  
01746976   Mihail   fix errors with w...
98
                  $file_name = $model->record_id . '.' . $model->file->extension;
9e481998   Mihail   add auto upload a...
99
100
  
                  if ($model->mode) {
34d480b7   Mihail   temp commit - wor...
101
                      $model->file_path = Yii::getAlias('@temp_upload') . '/' . $file_name;
9e481998   Mihail   add auto upload a...
102
103
104
                  } else {
                      $model->file_path = Yii::getAlias('@manual_upload') . '/' . $file_name;
                  }
500b481a   Administrator   JSON
105
  
dd60c760   Mihail   add menu and chec...
106
                  $model->file->saveAs($model->file_path);
9e481998   Mihail   add auto upload a...
107
108
109
                  // для авто загрузки, обработка завершена
                  if ($model->mode) {
                      $model->success = true;
34d480b7   Mihail   temp commit - wor...
110
  
9e481998   Mihail   add auto upload a...
111
112
113
114
                      return $this->render('index', ['model' => $model]);
                  }
  
                  // === ручная загрузка ===========
8894c93a   Mihail   add Importers fil...
115
                  //запускаем парсинг
f5769826   Mihail   add modal form fo...
116
                  // доп. опции для парсера
ffd4b834   Mihail   add articul filte...
117
118
119
120
                  $options = ['converter_conf' =>
                      ['importer_id' => $files_model->importer_id]
                  ];
  
f5769826   Mihail   add modal form fo...
121
122
123
124
                  if( ! $model->action ) // обработка с кастомным разделителем
                      $options['$delimiter'] = $model->delimiter;
  
                  $data = $model->readFile( $options );
8894c93a   Mihail   add Importers fil...
125
126
127
128
                  // сохраняем в кеш отпарсенные даные
                  Yii::$app->getCache()->set('parser_data', json_encode($data));
                  // сохраняем в кеш модель - в ней настройки для дальнейшей обработки данных
                  Yii::$app->getCache()->set('parser_configuration', serialize($model));
500b481a   Administrator   JSON
129
  
9e481998   Mihail   add auto upload a...
130
131
              } else {
                  // не прошла валидация форма загрузки файлов
4f3f27e8   Mihail   temp commit - tes...
132
133
134
135
136
137
  //                $errors_str = '';
  //                foreach ($model->getErrors() as $error) {
  //                    $errors_str .= implode( array_values($error) );
  //                }
  //               throw new ErrorException( $errors_str );
                  $model->throwStringErrorException();
3cf42f5c   Mihail   init commit - bas...
138
              }
8894c93a   Mihail   add Importers fil...
139
140
              // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные
          } else if (Yii::$app->getCache()->get('parser_data')) {
500b481a   Administrator   JSON
141
  
8894c93a   Mihail   add Importers fil...
142
              $data = json_decode(Yii::$app->getCache()->get('parser_data'), true);
500b481a   Administrator   JSON
143
  
3cf42f5c   Mihail   init commit - bas...
144
145
          }
  
474f35bf   Mihail   add DynamicFormHe...
146
147
148
149
150
151
152
          $provider = new ArrayDataProvider([
              'allModels' => $data,
              'pagination' => [
                  'pageSize' => 10,
              ],
          ]);
  
38a1a201   Mihail   add delete func i...
153
154
          $last_index = end( array_flip( $data[0] ) );
          $header_counts = $last_index + 1;
8894c93a   Mihail   add Importers fil...
155
          //формируем заголовок для пользователя, где он сможет выбрать соответсвие полей (выпадающий список)
38a1a201   Mihail   add delete func i...
156
          $header_model = DynamicFormHelper::CreateDynamicModel( $header_counts );
474f35bf   Mihail   add DynamicFormHe...
157
  
474f35bf   Mihail   add DynamicFormHe...
158
159
160
          return $this->render('results',
              ['model' => $data,
                  'header_model' => $header_model,
8894c93a   Mihail   add Importers fil...
161
162
                  // список колонок для выбора
                  'basic_column' => Yii::$app->multiparser->getConfiguration('csv', 'basic_column'),
474f35bf   Mihail   add DynamicFormHe...
163
                  'dataProvider' => $provider]);
3cf42f5c   Mihail   init commit - bas...
164
      }
474f35bf   Mihail   add DynamicFormHe...
165
  
8894c93a   Mihail   add Importers fil...
166
167
      public function actionWrite()
      {
8894c93a   Mihail   add Importers fil...
168
169
170
171
172
173
174
175
          //получим колонки которые выбрал пользователь
          $arr_attributes = Yii::$app->request->post()['DynamicModel'];
          //соберем модель по полученным данным
          $model = DynamicFormHelper::CreateDynamicModel($arr_attributes);
          //добавим правила валидации (колонки должны быть те что указаны в конфиге)
          foreach ($arr_attributes as $key => $value) {
              $model->addRule($key, 'in', ['range' => array_keys(Yii::$app->multiparser->getConfiguration('csv', 'basic_column'))]);
          }
474f35bf   Mihail   add DynamicFormHe...
176
  
8894c93a   Mihail   add Importers fil...
177
178
          // провалидируем выбранные колонки
          if ($model->validate()) {
28253169   Mihail   add converter as ...
179
  
8894c93a   Mihail   add Importers fil...
180
181
              // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы
              $arr = $model->toArray();
aa518ad3   Mihail   finishing with co...
182
  
8894c93a   Mihail   add Importers fil...
183
184
185
186
187
              // получим данные из кеша
              if (Yii::$app->getCache()->get('parser_data') && Yii::$app->getCache()->get('parser_configuration')) {
                  $data = json_decode(Yii::$app->getCache()->get('parser_data'), true);
                  $configuration = unserialize(Yii::$app->getCache()->get('parser_configuration'));
              } else {
2edfb901   Mihail   add PriceWriter a...
188
                  throw new \ErrorException('Ошибка кеша');
8894c93a   Mihail   add Importers fil...
189
              }
474f35bf   Mihail   add DynamicFormHe...
190
  
8894c93a   Mihail   add Importers fil...
191
192
              // соотнесем отпарсенные данные с соответсивем полученным от пользователя
              // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию
6215a30d   Mihail   add converter int...
193
              $data = CustomArrayHelper::createAssocArray( $data, $arr , 'attr_' );
8894c93a   Mihail   add Importers fil...
194
  
2edfb901   Mihail   add PriceWriter a...
195
196
197
198
199
200
              // запустим специальный класс который запишет данные в таблицы связанные с прайсами
              $writer = new PriceWriter();
              $writer->configuration = $configuration;
              $writer->data = $data;
              $writer->mode = 0; //web-режим
              if ( $writer->writeDataToDB() ) {
8894c93a   Mihail   add Importers fil...
201
  
2edfb901   Mihail   add PriceWriter a...
202
203
204
205
                  $configuration['success'] = true;
                  // все прошло успешно - очищаем кеш
                  Yii::$app->getCache()->delete('parser_data');
                  Yii::$app->getCache()->delete('parser_configuration');
9e481998   Mihail   add auto upload a...
206
  
3da8b25f   Mihail   fixed issues with...
207
208
209
                  if( file_exists($configuration['file_path']) )
                      unlink($configuration['file_path']);
  
2edfb901   Mihail   add PriceWriter a...
210
                  return $this->render('index', ['model' => $configuration]);
8894c93a   Mihail   add Importers fil...
211
  
2edfb901   Mihail   add PriceWriter a...
212
              };
8894c93a   Mihail   add Importers fil...
213
214
215
216
  
          }
  
      }
3cf42f5c   Mihail   init commit - bas...
217
  
9e481998   Mihail   add auto upload a...
218
219
      public function actionAutoUpload()
      {
1967135b   Mihail   adapt project to ...
220
          $query = Importers::find()->where(['active' => true])->orderBy(['price_date_update' => SORT_DESC]);
9e481998   Mihail   add auto upload a...
221
222
223
224
225
226
227
228
229
230
231
  
          $provider = new ActiveDataProvider([
              'query' => $query,
              'pagination' => [
                  'pageSize' => 10,
              ],
          ]);
          return $this->render('check_price',
              [
                  'dataProvider' => $provider]);
      }
9075f464   Mihail   add action and vi...
232
233
234
  
      public function actionServerFiles ()
      {
34d480b7   Mihail   temp commit - wor...
235
236
              $arr_id_files = [];
  
9075f464   Mihail   add action and vi...
237
          // получим список файлов которые ожидают к загрузке
df629228   Mihail   console csv parsing
238
          foreach ( glob(Yii::getAlias('@temp_upload') . '/*.csv' ) as $server_file ) {
9075f464   Mihail   add action and vi...
239
              $file_id = basename($server_file,".csv");
ae27b007   Mihail   add ajax handler ...
240
              $arr_id_files[] = (int) $file_id;
9075f464   Mihail   add action and vi...
241
          }
98533894   Mihail   merge with server
242
  
1967135b   Mihail   adapt project to ...
243
          $query = ImportersFiles::find()->where(['in', 'id', $arr_id_files])->orderBy(['upload_time' => SORT_DESC]);
9075f464   Mihail   add action and vi...
244
245
246
247
248
249
250
251
252
253
254
255
  
          $provider = new ActiveDataProvider([
              'query' => $query,
              'pagination' => [
                  'pageSize' => 10,
              ],
          ]);
          return $this->render('server-files',
              [
                  'dataProvider' => $provider]);
      }
  
ae27b007   Mihail   add ajax handler ...
256
      public function actionDelete ()
9075f464   Mihail   add action and vi...
257
      {
ae27b007   Mihail   add ajax handler ...
258
          if ( Yii::$app->request->isAjax ) {
9075f464   Mihail   add action and vi...
259
  
1967135b   Mihail   adapt project to ...
260
              $files_model = new ImportersFiles();
ae27b007   Mihail   add ajax handler ...
261
262
263
264
              if ( isset(Yii::$app->request->post()['id'] )) {
                  $id = Yii::$app->request->post()['id'];
                  try {
                      $files_model->delete($id);
34d480b7   Mihail   temp commit - wor...
265
                      unlink(Yii::getAlias('@temp_upload') . '/' . $id . '.csv' );
ae27b007   Mihail   add ajax handler ...
266
267
268
                      // сообщим скрипту что все ОК
                      echo 1;
                  } catch (ErrorException  $e) {
9075f464   Mihail   add action and vi...
269
  
93e39994   Mihail   fixed parser and ...
270
                      throw $e;
9075f464   Mihail   add action and vi...
271
  
ae27b007   Mihail   add ajax handler ...
272
273
                  }
              }
9075f464   Mihail   add action and vi...
274
275
          }
  
9075f464   Mihail   add action and vi...
276
      }
93e39994   Mihail   fixed parser and ...
277
  
34d480b7   Mihail   temp commit - wor...
278
279
      public function actionLaunchCroneUploads ()
      {
34d480b7   Mihail   temp commit - wor...
280
          foreach (glob(Yii::getAlias('@temp_upload') . '/*.csv') as $server_file) {
93e39994   Mihail   fixed parser and ...
281
  
34d480b7   Mihail   temp commit - wor...
282
              $file_name = basename($server_file,".csv");
df629228   Mihail   console csv parsing
283
              copy( $server_file, Yii::getAlias('@auto_upload') . '/' . $file_name . '.csv' );
34d480b7   Mihail   temp commit - wor...
284
285
  
          }
d3cf6647   Mihail   add multiply pric...
286
  
df629228   Mihail   console csv parsing
287
288
          Yii::$app->session->setFlash( 'server-files', 'Файл успешно загружен' );
          $this->redirect('server-files');
93e39994   Mihail   fixed parser and ...
289
  
d3cf6647   Mihail   add multiply pric...
290
291
  //        $csv = new \console\controllers\ParserController( 'parse-csv', $this->module );
  //        $csv->actionParseCsv();
0bec979b   Mihail   finish with xml a...
292
      }
93e39994   Mihail   fixed parser and ...
293
  
4f3f27e8   Mihail   temp commit - tes...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
      private function mailTest(){
  
          $mail_reader = new ImapMailReader( '{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'tsurkanovm@gmail.com', 'Wtvr@2000' );
          $mailboxes = $mail_reader->getListMailboxes();
          $files = [];
          foreach ( $mailboxes as $custom_label ) {
              $words = explode(" ",str_replace( array($mail_reader->getHostname(),"!"),"",imap_utf7_decode($custom_label)) );
              $importer_id = (int)preg_replace("/[^A-Z0-9]+/","", strtoupper($words[0]));
  
              $mail_reader->reOpen( $custom_label );
              $saver = new MailAttachmentsSaver( $mail_reader );
              if ( $importer_id ) {
                  $saver->setFileNamePrefix(  $importer_id . '~!~' );
              }
  
              if( $saver->saveAttachmentsTo(\Yii::getAlias('@temp_upload'), 'UNSEEN') ){
                  $files = array_merge( $files, $saver->getSavedFilesArr() );
              }else{
                  continue;
              }
  
          }
  
          if ( !$files ) {
              return;
          }
  
          $arch_creator = new ArchiveCreator();
          $arch_extensions = $arch_creator->getHandleExtension();
          $arch_files = array_intersect( $files , $arch_extensions );
          foreach ($arch_files as $arch_name => $arch_ext) {
              $arch_reader = $arch_creator->create( $arch_name, $arch_ext );
              $arch_reader->extractTo(\Yii::getAlias('@temp_upload'));
              unset( $files[$arch_name] );
              $files = array_merge( $files, $arch_reader->getExtractedFiles());
          }
  
          $new_destination = \Yii::getAlias('@auto_upload')  . '/';
          foreach ( $files as $name => $ext ) {
  
              $file_name = pathinfo($name, PATHINFO_FILENAME) . '.' . $ext;
              if( $ext = 'csv' ){
                  $files_model = new ImportersFiles();
                  $files_model->importer_id = $importer_id;
                  if ($files_model->save()) {
  
                      $file_name = \Yii::$app->db->getLastInsertID() . '.csv';
  
                  } else{
  
                      $files_model->throwStringErrorException();
                  }
  
              }
              $new_destination .=  $file_name;
              if( rename( $name, $new_destination ) ){
  
                  CustomVarDamp::dump('1111111');
  
              } else{
                  new \ErrorException("Нет возможности переписать файл {$name}");
              }
  
          }
  
      }
34d480b7   Mihail   temp commit - wor...
360
  
3cf42f5c   Mihail   init commit - bas...
361
  }