Blame view

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