[ 'class' => AccessControl::className(), 'rules' => [ [ 'allow' => true, 'roles' => ['@'], ], ], ], // 'verbs' => [ // 'class' => VerbFilter::className(), // 'actions' => [ // 'logout' => ['post'], // ], // ], ]; } public function actionIndex($mode = 0) { $model = new UploadFileParsingForm(); // установим режим, 0 - ручная загрузка, 1 - автозагрузка $model->mode = $mode; //CustomVarDamp::dumpAndDie(phpinfo()); return $this->render('index', ['model' => $model]); } public function actionError() { $exception = Yii::$app->errorHandler->exception; if ($exception !== null) { return $this->render('error', ['message' => $exception->getMessage()]); } } public function actionResults($mode = 0) { $model = new UploadFileParsingForm(['mode' => $mode]); $data = []; if ($model->load(Yii::$app->request->post())) { $model->file = UploadedFile::getInstance($model, 'file'); // первый проход - валидируем, сохраняем файл, ложим в кеш (для ручной загрузки) отпарсенные данные и параметры модели (потом при записи в базу данных они пригодятся) if ($model->validate()) { // запишем дату загрузки файла в таблицу файлов поставщика (ImportersFiles) $files_model = new ImportersFiles(); // id поставщика получим из конфигурации $files_model->load(['ImportersFiles' => $model->toArray()]); try { $files_model->save(); } catch (ErrorException $e) { // CustomVarDamp::dump($e->getMessage()); throw $e; } // получим id только что записанной записи - его запишем в название файла $model->record_id = $files_model->find() ->where(['importer_id' => $files_model->importer_id]) ->orderBy(['id' => SORT_DESC]) ->one() ->id; $file_name = $model->record_id . '.' . $model->file->extension; if ($model->mode) { $model->file_path = Yii::getAlias('@auto_upload') . '/' . $file_name; } else { $model->file_path = Yii::getAlias('@manual_upload') . '/' . $file_name; } $model->file->saveAs($model->file_path); // для авто загрузки, обработка завершена if ($model->mode) { $model->success = true; return $this->render('index', ['model' => $model]); } // === ручная загрузка =========== //запускаем парсинг $data = $model->readFile(); // сохраняем в кеш отпарсенные даные Yii::$app->getCache()->set('parser_data', json_encode($data)); // сохраняем в кеш модель - в ней настройки для дальнейшей обработки данных Yii::$app->getCache()->set('parser_configuration', serialize($model)); } else { // не прошла валидация форма загрузки файлов //@todo - отправка на страницу ошибок $errors_arr = $model->getErrors(); foreach ($errors_arr as $error) { CustomVarDamp::dump(array_values($error)); } die; } // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные } else if (Yii::$app->getCache()->get('parser_data')) { $data = json_decode(Yii::$app->getCache()->get('parser_data'), true); } $provider = new ArrayDataProvider([ 'allModels' => $data, 'pagination' => [ 'pageSize' => 10, ], ]); //формируем заголовок для пользователя, где он сможет выбрать соответсвие полей (выпадающий список) $header_model = DynamicFormHelper::CreateDynamicModel(count($data[0])); return $this->render('results', ['model' => $data, 'header_model' => $header_model, // список колонок для выбора 'basic_column' => Yii::$app->multiparser->getConfiguration('csv', 'basic_column'), 'dataProvider' => $provider]); } public function actionWrite() { //получим колонки которые выбрал пользователь $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'))]); } // провалидируем выбранные колонки if ($model->validate()) { // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы $arr = $model->toArray(); // получим данные из кеша 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 { throw new \ErrorException('Ошибка кеша'); } // соотнесем отпарсенные данные с соответсивем полученным от пользователя // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию $data = \Yii::$app->multiparser->convertToAssocArray($data, $arr, 'attr_'); // запустим специальный класс который запишет данные в таблицы связанные с прайсами $writer = new PriceWriter(); $writer->configuration = $configuration; $writer->data = $data; $writer->mode = 0; //web-режим if ( $writer->writeDataToDB() ) { $configuration['success'] = true; // все прошло успешно - очищаем кеш Yii::$app->getCache()->delete('parser_data'); Yii::$app->getCache()->delete('parser_configuration'); unlink($configuration['file_path']); return $this->render('index', ['model' => $configuration]); }; } } public function actionAutoUpload() { $query = Importers::find()->where(['active' => true])->orderBy(['price_date_update' => SORT_DESC]); $provider = new ActiveDataProvider([ 'query' => $query, 'pagination' => [ 'pageSize' => 10, ], ]); return $this->render('check_price', [ 'dataProvider' => $provider]); } public function actionServerFiles () { $arr_id_files = []; // получим список файлов которые ожидают к загрузке foreach (glob(Yii::getAlias('@auto_upload') . '/*') as $server_file) { $file_id = basename($server_file,".csv"); $arr_id_files[] = (int) $file_id; } Yii::$app->cache->set( 'files_to_parse',json_encode( $arr_id_files ) ); $query = ImportersFiles::find()->where(['in', 'id', $arr_id_files])->orderBy(['upload_time' => SORT_DESC]); $provider = new ActiveDataProvider([ 'query' => $query, 'pagination' => [ 'pageSize' => 10, ], ]); return $this->render('server-files', [ 'dataProvider' => $provider]); } public function actionDelete () { if ( Yii::$app->request->isAjax ) { $files_model = new ImportersFiles(); if ( isset(Yii::$app->request->post()['id'] )) { $id = Yii::$app->request->post()['id']; try { $files_model->delete($id); unlink(Yii::getAlias('@auto_upload') . '/' . $id . '.csv' ); // удалим этот id и из кэша if( $arr_id_files = Yii::$app->cache->get( 'files_to_parse' ) ){ $arr_id_files = json_decode($arr_id_files); if (isset( $arr_id_files[$id] ) ) { unset( $arr_id_files[$id] ); // положем уже обновленный массив Yii::$app->cache->set( 'files_to_parse',json_encode( $arr_id_files ) ); } } // сообщим скрипту что все ОК echo 1; } catch (ErrorException $e) { //CustomVarDamp::dump($e->getMessage()); throw $e; } } } } public function actionParse () { // $comand = "/usr/bin/php -f ".Yii::getAlias('@console') ."/Controllers/ParserController.php"; // exec($comand); if( $arr_id_files = Yii::$app->cache->get( 'files_to_parse' ) ) { $arr_id_files = json_decode( $arr_id_files ); foreach ( $arr_id_files as $file_name ) { $file_path = Yii::getAlias('@auto_upload') . '/' . $file_name . '.csv'; $config = ['record_id' => $file_name, 'importer_id' => ImportersFiles::findOne(['id' => $file_name])->id, 'parser_config' => ['keys' => ['DESCR', 'ARTICLE', 'BRAND', 'PRICE', 'BOX'], 'mode' => 'console'] ]; if( $this->parseFileConsole( $file_path, $config ) ){ unlink( $file_path ); if (isset( $arr_id_files[$file_path] ) ) { unset($arr_id_files[$file_path]); } } else { // Yii::$app->log-> // не дошли до конца по этому остаки вернем в кеш Yii::$app->cache->set( 'files_to_parse',json_encode( $arr_id_files ) ); } } if ( !count( $arr_id_files ) ) { Yii::$app->cache->delete( 'files_to_parse' ); } } return $this->redirect('serverFiles'); } protected function parseFileConsole( $file_path, $configuration ){ $parser_config = []; if ( isset( $configuration['parser_config'] ) ) { $parser_config = $configuration['parser_config']; } $data = Yii::$app->multiparser->parse( $file_path, $parser_config ); CustomVarDamp::dumpAndDie($data); $writer = new PriceWriter(); $writer->configuration = $configuration; $writer->data = $data; $writer->mode = 1; //console-режим if ( $writer->writeDataToDB() ){ //Console::output('It is working'); return true; } return false; } }