Blame view

console/controllers/ParserController.php 12 KB
f0dbd829   Mihail   add PriceWriter a...
1
  <?php
db543d22   Mihail   temp commit - wor...
2
3
  namespace console\controllers;
  
d73ee737   Mihail   finish with mail ...
4
  use common\components\archives\ArchiveCreator;
78684ed4   Mihail   add multiply pric...
5
  use common\components\CustomVarDamp;
8b0defd0   Mihail   add mails classes
6
7
  use common\components\mail\ImapMailReader;
  use common\components\mail\MailAttachmentsSaver;
f0dbd829   Mihail   add PriceWriter a...
8
  use yii\console\Controller;
1fe29bbe   Mihail   fixed parser and ...
9
10
11
  use yii\helpers\Console;
  use common\components\PriceWriter;
  use backend\models\ImportersFiles;
ef41533d   Mihail   temp commit - wor...
12
13
  use backend\models\Importers;
  use yii\base\ErrorException;
f0dbd829   Mihail   add PriceWriter a...
14
  
48b58a13   Mihail   finish with xml a...
15
16
  class ParserController extends Controller
  {
48b58a13   Mihail   finish with xml a...
17
      public function actionParseCsv()
f0dbd829   Mihail   add PriceWriter a...
18
      {
48b58a13   Mihail   finish with xml a...
19
20
21
22
          \Yii::info('Начало загрузки файлов прайсов csv', 'parser');
          foreach (glob(\Yii::getAlias('@auto_upload') . '/*.csv') as $file_path) {
              $file_name = basename($file_path, ".csv");
              \Yii::info("Обработка файла - $file_path", 'parser');
ea4ecf3d   Mihail   console csv parsing
23
              $importer_id = ImportersFiles::findOne(['id' => $file_name])->importer_id;
78684ed4   Mihail   add multiply pric...
24
25
26
27
28
29
30
31
32
              $current_importer = Importers::findOne(['id' => $importer_id]);
              $keys = $current_importer->keys;
              $mult_array = $current_importer->multiply;
  
              // получим настройки ценообразования и передадим их отдельно в конвертер
              $sign = '';
              $multiplier = '';
              extract( $mult_array );
  
ef41533d   Mihail   temp commit - wor...
33
  
ea4ecf3d   Mihail   console csv parsing
34
35
36
              $config = ['record_id' => $file_name,
                  'importer_id' => $importer_id,
                  'parser_config' => ['keys' => $keys,
78684ed4   Mihail   add multiply pric...
37
                      'converter_conf' =>
97dbfb3f   Administrator   upload project
38
39
                      ['sign' => $sign,
                      'multiplier' => $multiplier],
ea4ecf3d   Mihail   console csv parsing
40
41
                      'mode' => 'console']
              ];
7c1201d1   Mihail   add validator for...
42
              if ( $this->parseFileConsole( $file_path, $config ) ) {
48b58a13   Mihail   finish with xml a...
43
44
45
46
                  unlink(\Yii::getAlias('@temp_upload') . '/' . $file_name . '.csv');
                  \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser');
              } else {
                  \Yii::error("Загрузка файла - $file_path завершена с ошибкой", 'parser');
ea4ecf3d   Mihail   console csv parsing
47
              }
48b58a13   Mihail   finish with xml a...
48
49
              //при любом завершении скрипта файл с очереди автозагрузки нужно удалить
              unlink(\Yii::getAlias('@auto_upload') . '/' . $file_name . '.csv');
ea4ecf3d   Mihail   console csv parsing
50
          }
ef41533d   Mihail   temp commit - wor...
51
  
f0dbd829   Mihail   add PriceWriter a...
52
      }
ef41533d   Mihail   temp commit - wor...
53
  
f0dbd829   Mihail   add PriceWriter a...
54
  
1fe29bbe   Mihail   fixed parser and ...
55
      protected function parseFileConsole( $file_path, $configuration ){
ef41533d   Mihail   temp commit - wor...
56
57
  
          if( !file_exists( $file_path ) )
ea4ecf3d   Mihail   console csv parsing
58
              throw new ErrorException("$file_path - файл не найден!");
ef41533d   Mihail   temp commit - wor...
59
  
1fe29bbe   Mihail   fixed parser and ...
60
61
62
63
          $parser_config = [];
          if ( isset( $configuration['parser_config'] ) ) {
              $parser_config = $configuration['parser_config'];
          }
ef41533d   Mihail   temp commit - wor...
64
          $data = \Yii::$app->multiparser->parse( $file_path, $parser_config );
78684ed4   Mihail   add multiply pric...
65
          if ( ! $data ) {
78fd7100   Mihail   add XlsxParser
66
              throw new ErrorException("Ошибка обработки файла прайса!");
ea4ecf3d   Mihail   console csv parsing
67
          }
f0dbd829   Mihail   add PriceWriter a...
68
  
1fe29bbe   Mihail   fixed parser and ...
69
          $writer = new PriceWriter();
edfa67b1   Mihail   add delete price ...
70
71
72
          $writer->setConfiguration( $configuration );
          $writer->setData( $data );
          $writer->setMode( 1 ); //console-режим
ea4ecf3d   Mihail   console csv parsing
73
  
7c1201d1   Mihail   add validator for...
74
75
76
77
78
79
80
          $writer->writePriceToDB();
              if ( $writer->hasValidationError() ) {
                  \Yii::error( $writer->getValidatedMsg(), 'parser' );
              }else{
                  \Yii::info( $writer->getValidatedMsg(), 'parser' );
              }
  
ea4ecf3d   Mihail   console csv parsing
81
  
1fe29bbe   Mihail   fixed parser and ...
82
              return true;
f0dbd829   Mihail   add PriceWriter a...
83
  
f0dbd829   Mihail   add PriceWriter a...
84
      }
db543d22   Mihail   temp commit - wor...
85
  
ea4ecf3d   Mihail   console csv parsing
86
87
      public function actionParseXml ()
      {
48b58a13   Mihail   finish with xml a...
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
           \Yii::info('Начало загрузки файлов прайсов xml', 'parser');
          foreach (glob(\Yii::getAlias('@auto_upload') . '/*.xml') as $file_path) {
              $file_name = basename($file_path, ".xml");
                    \Yii::info("Обработка файла - $file_path", 'parser');
  
              $files_model = new ImportersFiles();
              // id поставщика всегда = 1 - Склад
              $files_model->importer_id = 1;
              try {
                  $files_model->save();
              } catch (ErrorException  $e) {
                  throw $e;
              }
              // получим id только что записанной записи
              $record_id = $files_model->find()
                  ->where(['importer_id' => $files_model->importer_id])
                  ->orderBy(['id' => SORT_DESC])
                  ->one()
                  ->id;
  
              $config = ['record_id' => $record_id,
                  'importer_id' => 1,
                  'parser_config' => [
                      'mode' => 'console']
              ];
ea4ecf3d   Mihail   console csv parsing
113
  
48b58a13   Mihail   finish with xml a...
114
              if ($this->parseFileConsole($file_path, $config)) {
78fd7100   Mihail   add XlsxParser
115
                  //unlink(\Yii::getAlias('@auto_upload') . '/' . $file_name . '.xml');
48b58a13   Mihail   finish with xml a...
116
117
118
119
120
                          \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser');
              } else {
                          \Yii::error("Загрузка файла - $file_path завершена с ошибкой", 'parser');
              }
          }
ea4ecf3d   Mihail   console csv parsing
121
122
      }
  
48b58a13   Mihail   finish with xml a...
123
      public function actionTest()
db543d22   Mihail   temp commit - wor...
124
      {
8f043ab6   Mihail   add classes to wo...
125
          Console::output('It is working');
48b58a13   Mihail   finish with xml a...
126
          \Yii::info('2', 'parser');
db543d22   Mihail   temp commit - wor...
127
128
  
      }
8b0defd0   Mihail   add mails classes
129
130
131
132
133
  
      public function actionSaveMailAttachments()
      {
          \Yii::info('Начало сохранения файлов почты', 'mail');
  
d73ee737   Mihail   finish with mail ...
134
135
136
          // получим разделитель для файлов поставщика
          $importer_id_prefix = ImportersFiles::FILES_PREFIX;
          // подключимся к ящику
8b0defd0   Mihail   add mails classes
137
          $mail_reader = new ImapMailReader( '{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'tsurkanovm@gmail.com', 'Wtvr@2000' );
6f678cad   Mihail   refactored SaveMa...
138
139
  
          // 1. получим все вложения
1fd14fc9   Mihail   fixed errors with...
140
          \Yii::info('Начало сохранения файлов почты', 'mail');
6f678cad   Mihail   refactored SaveMa...
141
142
          $files = $this->getMailAttachments( $mail_reader, $importer_id_prefix );
  
6f678cad   Mihail   refactored SaveMa...
143
144
          if ( !$files ) {
              // нет файлов в ящиках (не было вложений в письмах)
1fd14fc9   Mihail   fixed errors with...
145
              \Yii::warning('Вложений не найдено', 'mail');
6f678cad   Mihail   refactored SaveMa...
146
147
148
              return;
          }
  
1fd14fc9   Mihail   fixed errors with...
149
150
151
152
153
          // 2. если в вложениях есть архивы - распакуем их и дополним итоговый массив
          \Yii::info('Запуск распаковки архивов...', 'mail');
          $this->UnpackFiles( $files );
  
  
6f678cad   Mihail   refactored SaveMa...
154
155
          // 3. переименуем, зарегистрируем прайсы и перенесем извлеченные файлы
          // укажем папку куда нужно перенести все извлеченные вложения
1fd14fc9   Mihail   fixed errors with...
156
          \Yii::info('Запуск перемещения и регистрации прайсов...', 'mail');
6f678cad   Mihail   refactored SaveMa...
157
158
159
160
161
162
163
164
165
          $new_destination = \Yii::getAlias('@auto_upload')  . '/';
  
          $this->registerAndReplaceFiles( $files, $new_destination );
  
  
      }
  
      private function getMailAttachments ($mail_reader, $importer_id_prefix = '')
      {
d73ee737   Mihail   finish with mail ...
166
          // получим все внутренние ящики (по ярлыкам)
8b0defd0   Mihail   add mails classes
167
          $mailboxes = $mail_reader->getListMailboxes();
d73ee737   Mihail   finish with mail ...
168
169
          // очистим массив в котором в итоге окажуться все файлы вложений, а также распакованные файлы из архивов
          $files = [];
8f043ab6   Mihail   add classes to wo...
170
          foreach ( $mailboxes as $custom_label ) {
d73ee737   Mihail   finish with mail ...
171
172
              // получим поставщика исходя из маски ярлыка
              $importer_id = ImportersFiles::getIdFromMailBox( $mail_reader->getHostname(), $custom_label );
8b0defd0   Mihail   add mails classes
173
  
d73ee737   Mihail   finish with mail ...
174
              // читаем письма конкретного ярлыка
8f043ab6   Mihail   add classes to wo...
175
              $mail_reader->reOpen( $custom_label );
d73ee737   Mihail   finish with mail ...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
              // создадим сейвер вложений для данного ярлыка (ящика)
              $saver = new MailAttachmentsSaver( $mail_reader );
              // если данный ярлык содержит id поставщика, то все вложения нужно промаркировать (в начало файла добавить id поставщика + разделитель $importer_id_prefix)
              if ( $importer_id ) {
                  $saver->setFileNamePrefix(  $importer_id . $importer_id_prefix );
                  //    $importer_id = '';
              }
              // сохраняем вложения
              if( $saver->saveAttachmentsTo(\Yii::getAlias('@temp_upload'), 'UNSEEN') ){
                  // закидываем вытащенные файлы в наш итоговый массив
                  $files = array_merge( $files, $saver->getSavedFilesArr() );
              }else{
                  // ящик не имеет писем с вложениями
                  continue;
              }
8b0defd0   Mihail   add mails classes
191
192
          }
  
6f678cad   Mihail   refactored SaveMa...
193
194
          return $files;
      }
d73ee737   Mihail   finish with mail ...
195
  
6f678cad   Mihail   refactored SaveMa...
196
197
      private function UnpackFiles ( &$files, $importer_id_prefix = '')
      {
d73ee737   Mihail   finish with mail ...
198
199
          // если в вложениях встречаются архивы - распакуем
          // иициируем фабрику архиваторов
8f043ab6   Mihail   add classes to wo...
200
          $arch_creator = new ArchiveCreator();
d73ee737   Mihail   finish with mail ...
201
          // получим все расширения которые поддерживает фабрика
8f043ab6   Mihail   add classes to wo...
202
          $arch_extensions = $arch_creator->getHandleExtension();
d73ee737   Mihail   finish with mail ...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
          // выбираем только те файлы которые мы можем распаковать
          $arch_files = array_intersect( $files , $arch_extensions );
          foreach ($arch_files as $arch_name => $arch_ext) {
              // создаем конкретный архиватор по расширению
              $arch_reader = $arch_creator->create( $arch_name, $arch_ext );
              // определим ид поставщика по имени файла
              $importer_id = ImportersFiles::getIdFromFileName($arch_name);
              if( $importer_id ){
                  // если файл архива содержит поставщика (на предыдущих этапах мы его туда записали)
                  // то нужно все вложенные файлы также промаркировать
                  $arch_reader->setFileNamePrefix($importer_id . $importer_id_prefix);
                  //$importer_id = '';
              }
  
              // распаковываем файлы
              $arch_reader->extractTo(\Yii::getAlias('@temp_upload') . '/');
              // убираем файл архива из итогового массива
8f043ab6   Mihail   add classes to wo...
220
              unset( $files[$arch_name] );
d73ee737   Mihail   finish with mail ...
221
222
223
              // удаляем файл архива
              unlink($arch_name);
              // добавляем распакованные файлы к итоговому массиву
8f043ab6   Mihail   add classes to wo...
224
225
226
              $files = array_merge( $files, $arch_reader->getExtractedFiles());
          }
  
6f678cad   Mihail   refactored SaveMa...
227
228
229
230
      }
  
      private function registerAndReplaceFiles ( &$files, $new_destination )
      {
c4da20f0   Mihail   temp commit - tes...
231
          foreach ( $files as $name => $ext ) {
6f678cad   Mihail   refactored SaveMa...
232
233
              // имена файлов для расширения csv нужно поменять,
              // для остальных оставляем оригинальные имена вложений (плюс ид поставщика если письмо от поставщика)
d73ee737   Mihail   finish with mail ...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
              $file_name = pathinfo( $name, PATHINFO_BASENAME );
              if( $ext == 'csv' ){
                  // определим ид поставщика по имени файла
                  $importer_id = ImportersFiles::getIdFromFileName( basename( $name ) );;
  
                  // зарегистрируем прайс
                  if ( $importer_id ) {
                      $files_model = new ImportersFiles();
                      $files_model->importer_id = $importer_id;
                      if ($files_model->save()) {
                          // имя файла переименуем на id записи
                          $file_name = \Yii::$app->db->getLastInsertID() . '.csv';
  
                      } else{
  
                          $files_model->throwStringErrorException();
                      }
                  }
d73ee737   Mihail   finish with mail ...
252
253
              }
              if( rename( $name, $new_destination . $file_name ) ){
6f678cad   Mihail   refactored SaveMa...
254
                  \Yii::info("Вложение {$name} сохранено", 'mail');
d73ee737   Mihail   finish with mail ...
255
256
              } else{
                  new \ErrorException("Нет возможности переписать файл {$name}");
c4da20f0   Mihail   temp commit - tes...
257
              }
8f043ab6   Mihail   add classes to wo...
258
          }
8b0defd0   Mihail   add mails classes
259
      }
f0dbd829   Mihail   add PriceWriter a...
260
  }