Commit 642796c8922bd5a628acb0a7760ee7315908d3ab
1 parent
3c5edb9b
merge with server
Showing
31 changed files
with
1334 additions
and
151 deletions
Show diff stats
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * Created by PhpStorm. | ||
| 4 | + * User: Cibermag | ||
| 5 | + * Date: 21.09.2015 | ||
| 6 | + * Time: 17:36 | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | +namespace backend\components\base; | ||
| 10 | + | ||
| 11 | +use yii\db\Connection; | ||
| 12 | + | ||
| 13 | +class CustomDbConnection extends Connection { | ||
| 14 | + //@todo - переписать с использованием событий - почемуто не сработало это событие | ||
| 15 | + public function afterOpen() | ||
| 16 | + { | ||
| 17 | + $now = new \DateTime(); | ||
| 18 | + $mins = $now->getOffset() / 60; | ||
| 19 | + $sgn = ($mins < 0 ? -1 : 1); | ||
| 20 | + $mins = abs($mins); | ||
| 21 | + $hrs = floor($mins / 60); | ||
| 22 | + $mins -= $hrs * 60; | ||
| 23 | + $offset = sprintf('%+d:%02d', $hrs*$sgn, $mins); | ||
| 24 | + | ||
| 25 | + $this->pdo->exec("SET time_zone='$offset';"); | ||
| 26 | + | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + protected function initConnection() | ||
| 30 | + { | ||
| 31 | + parent::initConnection(); | ||
| 32 | + $this->afterOpen(); | ||
| 33 | + | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + | ||
| 37 | +} | ||
| 0 | \ No newline at end of file | 38 | \ No newline at end of file |
| 1 | +<?php | ||
| 2 | +namespace backend\components\parsers; | ||
| 3 | +use yii\multiparser\Converter; | ||
| 4 | + | ||
| 5 | +class CustomConverter extends Converter { | ||
| 6 | + | ||
| 7 | + /** | ||
| 8 | + * @param $value_arr - двумерный массив значений, которому нужно присвоить ключи | ||
| 9 | + * @param $key_array - ключи для вложенного массива | ||
| 10 | + * @return array - таблица с проименованными колонками | ||
| 11 | + */ | ||
| 12 | + public static function convertToAssocArray ( array $value_arr, array $key_array, $key_prefix = '') | ||
| 13 | + { | ||
| 14 | + // очистка служебного префикса в массиве заголовков | ||
| 15 | + if ($key_prefix) { | ||
| 16 | + $params_array = array_fill( 0, count($key_array), $key_prefix ); | ||
| 17 | + //@todo переписать с использованием array_walk | ||
| 18 | + $key_array = array_map( function ($value, $key_prefix){ return str_replace( $key_prefix, '',$value ); }, $key_array, $params_array ); | ||
| 19 | + //уберем пустые элементы | ||
| 20 | + $key_array = array_filter($key_array, function ($value){ return $value !==''; }); | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + // преобразуем массив ключей (обернем в массив), для передачи его в качестве параметра в анонимную функцию для array_map | ||
| 24 | + // для этого увеличим размерность массива, что бы при каждом обходе массива $value_arr , функции был доступен исходный массив ключей | ||
| 25 | + $key_array = array_fill( 0, count($value_arr), $key_array ); | ||
| 26 | + // \common\components\CustomVarDamp::dumpAndDie($key_array); | ||
| 27 | + $result = array_map( | ||
| 28 | + function ($value, $key_array) { | ||
| 29 | + $res = $value; | ||
| 30 | + foreach ($value as $key => $sub_value) { | ||
| 31 | + if (isset($key_array[$key])) { | ||
| 32 | + // если такой ключ в базовом массиве (массиве ключей) есть, то заменим новым, иначе просто удалим | ||
| 33 | + $new_key = $key_array[$key]; | ||
| 34 | + if( !array_key_exists( $new_key , $res ) ){ | ||
| 35 | + $res[ $new_key ] = $res[$key]; | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + unset( $res[$key] ); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + return $res; | ||
| 42 | + }, | ||
| 43 | + $value_arr, $key_array); | ||
| 44 | + return $result; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * @param $value_arr - двумерный массив к которому нужно добавить колонки | ||
| 49 | + * @param $add_array - массив с колонками (ключи) и занчениями колонок | ||
| 50 | + * @return mixed | ||
| 51 | + */ | ||
| 52 | + public function addColumns ( array $value_arr , array $add_array ) | ||
| 53 | + { | ||
| 54 | + $i = 0; | ||
| 55 | + while ($i < count($value_arr)) { | ||
| 56 | + foreach ($add_array as $add_key => $add_value) { | ||
| 57 | + $value_arr[$i][$add_key] = $add_value; | ||
| 58 | + } | ||
| 59 | + $i++; | ||
| 60 | + } | ||
| 61 | + return $value_arr; | ||
| 62 | + } | ||
| 63 | +} | ||
| 0 | \ No newline at end of file | 64 | \ No newline at end of file |
backend/components/parsers/CustomCsvParser.php
| @@ -16,15 +16,27 @@ class CustomCsvParser extends \yii\multiparser\CsvParser { | @@ -16,15 +16,27 @@ class CustomCsvParser extends \yii\multiparser\CsvParser { | ||
| 16 | // public $keys = ['first','second', 'third', 'forth', 'fifth']; | 16 | // public $keys = ['first','second', 'third', 'forth', 'fifth']; |
| 17 | public function setupConverter() | 17 | public function setupConverter() |
| 18 | { | 18 | { |
| 19 | + if (!count($this->converter_conf)) { | ||
| 20 | + if ($this->hasHeaderRow) { | ||
| 21 | + // если у файла есть заголовок, то в результате имеем ассоциативный массив | ||
| 22 | + $this->converter_conf['hasKey'] = 1; | ||
| 23 | + } | ||
| 19 | 24 | ||
| 20 | - if ($this->hasHeaderRow) { | ||
| 21 | - // если у файла есть заголовок, то в результате имеем ассоциативный массив | ||
| 22 | - $this->converter_conf['hasKey'] = 1; | ||
| 23 | } | 25 | } |
| 24 | 26 | ||
| 25 | - $this->converter = \Yii::createObject($this->converter_conf); | ||
| 26 | - | ||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | + /** | ||
| 30 | + * @param $arr | ||
| 31 | + * @return mixed | ||
| 32 | + * преобразовует значения прочитанного массива в нужные типы, согласно конфигурации конвертера | ||
| 33 | + */ | ||
| 34 | + protected function convert($arr) | ||
| 35 | + { | ||
| 36 | + $result = \Yii::$app->multiparser->convertByConfiguration( $arr, $this->converter_conf ); | ||
| 37 | + | ||
| 38 | + return $result; | ||
| 39 | + | ||
| 40 | + } | ||
| 29 | 41 | ||
| 30 | } | 42 | } |
| 31 | \ No newline at end of file | 43 | \ No newline at end of file |
backend/components/parsers/config.php
| 1 | <?php | 1 | <?php |
| 2 | return [ | 2 | return [ |
| 3 | + 'global' => | ||
| 4 | + ['ini' => ['upload_max_filesize' => '20M', | ||
| 5 | + 'post_max_size integer' => '30M', | ||
| 6 | + ]], | ||
| 3 | 'csv' => | 7 | 'csv' => |
| 4 | ['web' => | 8 | ['web' => |
| 5 | ['class' => 'backend\components\parsers\CustomCsvParser', | 9 | ['class' => 'backend\components\parsers\CustomCsvParser', |
| 6 | 'auto_detect_first_line' => true, | 10 | 'auto_detect_first_line' => true, |
| 7 | - 'converter_conf' => ['class' => 'yii\multiparser\Converter', | ||
| 8 | - 'configuration' => [ | ||
| 9 | - "string" => 'DESCR' | ||
| 10 | - ] | ||
| 11 | - ,]], | 11 | + 'converter_conf' => ['class' => ' backend\components\parsers\CustomConverter', |
| 12 | + 'configuration' => ["string" => 'DESCR'],] | ||
| 13 | + ], | ||
| 12 | 14 | ||
| 13 | 'basic_column' => [ | 15 | 'basic_column' => [ |
| 14 | Null => 'Пусто', | 16 | Null => 'Пусто', |
backend/config/main.php
| @@ -43,6 +43,9 @@ return [ | @@ -43,6 +43,9 @@ return [ | ||
| 43 | 43 | ||
| 44 | 'class' => 'yii\multiparser\YiiMultiparser', | 44 | 'class' => 'yii\multiparser\YiiMultiparser', |
| 45 | 'configuration' => $mp_configuration, | 45 | 'configuration' => $mp_configuration, |
| 46 | + 'as behavior' => [ | ||
| 47 | + 'class' => 'backend\components\parsers\CustomConverter', | ||
| 48 | + ], | ||
| 46 | 49 | ||
| 47 | ], | 50 | ], |
| 48 | ], | 51 | ], |
| 1 | +<?php | ||
| 2 | +namespace backend\controllers; | ||
| 3 | + | ||
| 4 | +use Yii; | ||
| 5 | +use yii\bootstrap\Modal; | ||
| 6 | +use yii\data\ActiveDataProvider; | ||
| 7 | +use yii\filters\AccessControl; | ||
| 8 | +use backend\components\base\BaseController; | ||
| 9 | +use yii\filters\VerbFilter; | ||
| 10 | +use backend\models\Details; | ||
| 11 | +use backend\models\ImporterFiles; | ||
| 12 | +use backend\models\Importer; | ||
| 13 | +use yii\base\ErrorException; | ||
| 14 | + | ||
| 15 | +use common\components\CustomVarDamp; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * Parser controller | ||
| 19 | + */ | ||
| 20 | +class CheckPriceController extends BaseController | ||
| 21 | +{ | ||
| 22 | + public $layout = "/column"; | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * @inheritdoc | ||
| 26 | + */ | ||
| 27 | + public function behaviors() | ||
| 28 | + { | ||
| 29 | + return [ | ||
| 30 | + 'access' => [ | ||
| 31 | + 'class' => AccessControl::className(), | ||
| 32 | + 'rules' => [ | ||
| 33 | + [ | ||
| 34 | + 'actions' => ['index', 'view'], | ||
| 35 | + 'allow' => true, | ||
| 36 | + 'roles' => ['@'], | ||
| 37 | + ], | ||
| 38 | + ], | ||
| 39 | + ], | ||
| 40 | +// 'verbs' => [ | ||
| 41 | +// 'class' => VerbFilter::className(), | ||
| 42 | +// 'actions' => [ | ||
| 43 | +// 'logout' => ['post'], | ||
| 44 | +// ], | ||
| 45 | +// ], | ||
| 46 | + ]; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * @inheritdoc | ||
| 51 | + */ | ||
| 52 | + public function actions() | ||
| 53 | + { | ||
| 54 | + return [ | ||
| 55 | + 'error' => [ | ||
| 56 | + 'class' => 'yii\web\ErrorAction', | ||
| 57 | + ], | ||
| 58 | + ]; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + | ||
| 62 | + public function actionIndex() | ||
| 63 | + { | ||
| 64 | + if(Yii::$app->request->isAjax){ | ||
| 65 | + CustomVarDamp::dumpAndDie(1); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + //$query = (new Query())->select('*')->from('{{%importer_files}}')->where(['not', ['time_end' => null]])->orderBy(['upload_time' => SORT_DESC]); | ||
| 69 | + $query = Importer::find()->where(['active' => true])->orderBy(['price_date_update' => SORT_DESC]); | ||
| 70 | + | ||
| 71 | + $provider = new ActiveDataProvider([ | ||
| 72 | + 'query' => $query, | ||
| 73 | + 'pagination' => [ | ||
| 74 | + 'pageSize' => 10, | ||
| 75 | + ], | ||
| 76 | + ]); | ||
| 77 | + return $this->render('index', | ||
| 78 | + [ | ||
| 79 | + 'dataProvider' => $provider, | ||
| 80 | + ]); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + | ||
| 84 | + public function actionView ($id) | ||
| 85 | + { | ||
| 86 | + // @todo переписать запрос - нужно условие на равенство даты, а также вьюшка должна быть модальным окном вызываемой по аджаксу | ||
| 87 | + $query = Details::find()->where(['IMPORT_ID' => $id])->orderBy(['timestamp' => SORT_DESC]); | ||
| 88 | + | ||
| 89 | + $provider = new ActiveDataProvider([ | ||
| 90 | + 'query' => $query, | ||
| 91 | + 'pagination' => [ | ||
| 92 | + 'pageSize' => 16, | ||
| 93 | + ], | ||
| 94 | + ]); | ||
| 95 | + return $this->render('view', | ||
| 96 | + ['dataProvider' => $provider]); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | +} |
| 1 | +<?php | ||
| 2 | +namespace backend\controllers; | ||
| 3 | + | ||
| 4 | +use Yii; | ||
| 5 | +use yii\bootstrap\Modal; | ||
| 6 | +use yii\data\ActiveDataProvider; | ||
| 7 | +use yii\filters\AccessControl; | ||
| 8 | +use backend\components\base\BaseController; | ||
| 9 | +use yii\filters\VerbFilter; | ||
| 10 | +use backend\models\UploadFileParsingForm; | ||
| 11 | +use yii\web\UploadedFile; | ||
| 12 | +use yii\data\ArrayDataProvider; | ||
| 13 | +use yii\multiparser\DynamicFormHelper; | ||
| 14 | +use backend\components\parsers\CustomParserConfigurator; | ||
| 15 | +use backend\models\Details; | ||
| 16 | +use backend\models\ImporterFiles; | ||
| 17 | +use backend\models\Importer; | ||
| 18 | +use yii\base\ErrorException; | ||
| 19 | +use yii\db\Query; | ||
| 20 | + | ||
| 21 | +use common\components\CustomVarDamp; | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * Parser controller | ||
| 25 | + */ | ||
| 26 | +class Check_priceController extends BaseController | ||
| 27 | +{ | ||
| 28 | + public $layout = "/column"; | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * @inheritdoc | ||
| 32 | + */ | ||
| 33 | + public function behaviors() | ||
| 34 | + { | ||
| 35 | + return [ | ||
| 36 | + 'access' => [ | ||
| 37 | + 'class' => AccessControl::className(), | ||
| 38 | + 'rules' => [ | ||
| 39 | + [ | ||
| 40 | + 'actions' => ['index', 'view'], | ||
| 41 | + 'allow' => true, | ||
| 42 | + 'roles' => ['@'], | ||
| 43 | + ], | ||
| 44 | + ], | ||
| 45 | + ], | ||
| 46 | +// 'verbs' => [ | ||
| 47 | +// 'class' => VerbFilter::className(), | ||
| 48 | +// 'actions' => [ | ||
| 49 | +// 'logout' => ['post'], | ||
| 50 | +// ], | ||
| 51 | +// ], | ||
| 52 | + ]; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * @inheritdoc | ||
| 57 | + */ | ||
| 58 | + public function actions() | ||
| 59 | + { | ||
| 60 | + return [ | ||
| 61 | + 'error' => [ | ||
| 62 | + 'class' => 'yii\web\ErrorAction', | ||
| 63 | + ], | ||
| 64 | + ]; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + | ||
| 68 | + public function actionIndex() | ||
| 69 | + { | ||
| 70 | + | ||
| 71 | + if(Yii::$app->request->isAjax){ | ||
| 72 | + CustomVarDamp::dumpAndDie(1); | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + //$query = (new Query())->select('*')->from('{{%importer_files}}')->where(['not', ['time_end' => null]])->orderBy(['upload_time' => SORT_DESC]); | ||
| 76 | + $query = Importer::find()->where(['active' => true])->orderBy(['price_date_update' => SORT_DESC]); | ||
| 77 | + | ||
| 78 | + $provider = new ActiveDataProvider([ | ||
| 79 | + 'query' => $query, | ||
| 80 | + 'pagination' => [ | ||
| 81 | + 'pageSize' => 10, | ||
| 82 | + ], | ||
| 83 | + ]); | ||
| 84 | + return $this->render('index', | ||
| 85 | + [ | ||
| 86 | + 'dataProvider' => $provider, | ||
| 87 | + ]); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + | ||
| 91 | + public function actionView ($id) | ||
| 92 | + { | ||
| 93 | + | ||
| 94 | + | ||
| 95 | + | ||
| 96 | + | ||
| 97 | + $query = Details::find()->where(['IMPORT_ID' => $id])->orderBy(['timestamp' => SORT_DESC]); | ||
| 98 | + | ||
| 99 | + $provider = new ActiveDataProvider([ | ||
| 100 | + 'query' => $query, | ||
| 101 | + 'pagination' => [ | ||
| 102 | + 'pageSize' => 16, | ||
| 103 | + ], | ||
| 104 | + ]); | ||
| 105 | + return $this->render('view', | ||
| 106 | + ['dataProvider' => $provider]); | ||
| 107 | + } | ||
| 108 | +} |
backend/controllers/ParserController.php
| @@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
| 2 | namespace backend\controllers; | 2 | namespace backend\controllers; |
| 3 | 3 | ||
| 4 | use Yii; | 4 | use Yii; |
| 5 | +use yii\data\ActiveDataProvider; | ||
| 5 | use yii\filters\AccessControl; | 6 | use yii\filters\AccessControl; |
| 6 | use backend\components\base\BaseController; | 7 | use backend\components\base\BaseController; |
| 7 | use yii\filters\VerbFilter; | 8 | use yii\filters\VerbFilter; |
| @@ -10,16 +11,21 @@ use yii\web\UploadedFile; | @@ -10,16 +11,21 @@ use yii\web\UploadedFile; | ||
| 10 | use yii\data\ArrayDataProvider; | 11 | use yii\data\ArrayDataProvider; |
| 11 | use yii\multiparser\DynamicFormHelper; | 12 | use yii\multiparser\DynamicFormHelper; |
| 12 | use backend\components\parsers\CustomParserConfigurator; | 13 | use backend\components\parsers\CustomParserConfigurator; |
| 14 | +use backend\models\Details; | ||
| 15 | +use backend\models\ImporterFiles; | ||
| 16 | +use backend\models\Importer; | ||
| 17 | +use yii\base\ErrorException; | ||
| 18 | +use yii\db\Query; | ||
| 13 | 19 | ||
| 14 | use common\components\CustomVarDamp; | 20 | use common\components\CustomVarDamp; |
| 15 | 21 | ||
| 16 | /** | 22 | /** |
| 17 | * Parser controller | 23 | * Parser controller |
| 18 | */ | 24 | */ |
| 19 | - | ||
| 20 | class ParserController extends BaseController | 25 | class ParserController extends BaseController |
| 21 | { | 26 | { |
| 22 | public $layout = "/column"; | 27 | public $layout = "/column"; |
| 28 | + | ||
| 23 | /** | 29 | /** |
| 24 | * @inheritdoc | 30 | * @inheritdoc |
| 25 | */ | 31 | */ |
| @@ -30,7 +36,6 @@ class ParserController extends BaseController | @@ -30,7 +36,6 @@ class ParserController extends BaseController | ||
| 30 | 'class' => AccessControl::className(), | 36 | 'class' => AccessControl::className(), |
| 31 | 'rules' => [ | 37 | 'rules' => [ |
| 32 | [ | 38 | [ |
| 33 | - 'actions' => ['index','results','write'], | ||
| 34 | 'allow' => true, | 39 | 'allow' => true, |
| 35 | 'roles' => ['@'], | 40 | 'roles' => ['@'], |
| 36 | ], | 41 | ], |
| @@ -58,34 +63,84 @@ class ParserController extends BaseController | @@ -58,34 +63,84 @@ class ParserController extends BaseController | ||
| 58 | } | 63 | } |
| 59 | 64 | ||
| 60 | 65 | ||
| 61 | - | ||
| 62 | - public function actionIndex() | 66 | + public function actionIndex($mode = 0) |
| 63 | { | 67 | { |
| 64 | $model = new UploadFileParsingForm(); | 68 | $model = new UploadFileParsingForm(); |
| 65 | - | 69 | + // установим режим, 0 - ручная загрузка, 1 - автозагрузка |
| 70 | + $model->mode = $mode; | ||
| 71 | + //CustomVarDamp::dumpAndDie(phpinfo()); | ||
| 66 | return $this->render('index', ['model' => $model]); | 72 | return $this->render('index', ['model' => $model]); |
| 67 | } | 73 | } |
| 68 | 74 | ||
| 69 | - public function actionResults(){ | 75 | +// public function beforeAction($action) |
| 76 | +// { | ||
| 77 | +// if($action->actionMethod ='actionResults'){ | ||
| 78 | +// CustomVarDamp::dumpAndDie(phpinfo()); | ||
| 79 | +// } | ||
| 80 | +// } | ||
| 70 | 81 | ||
| 71 | - $model = new UploadFileParsingForm(); | 82 | + public function actionResults($mode = 0) |
| 83 | + { | ||
| 84 | + $model = new UploadFileParsingForm(['mode' => $mode]); | ||
| 72 | $data = []; | 85 | $data = []; |
| 73 | if ($model->load(Yii::$app->request->post())) { | 86 | if ($model->load(Yii::$app->request->post())) { |
| 74 | $model->file = UploadedFile::getInstance($model, 'file'); | 87 | $model->file = UploadedFile::getInstance($model, 'file'); |
| 75 | - | 88 | + // первый проход - валидируем, сохраняем файл, ложим в кеш (для ручной загрузки) отпарсенные данные и параметры модели (потом при записи в базу данных они пригодятся) |
| 76 | if ($model->validate()) { | 89 | if ($model->validate()) { |
| 77 | - $filePath = Yii::getAlias('@webroot') . '/uploads/' . $model->file->baseName . '.' . $model->file->extension; | 90 | + // запишем дату загрузки файла в таблицу файлов поставщика (ImportersFiles) |
| 91 | + $files_model = new ImporterFiles(); | ||
| 92 | + // id поставщика получим из конфигурации | ||
| 93 | + $files_model->load(['ImporterFiles' => $model->toArray()]); | ||
| 94 | + try { | ||
| 95 | + $files_model->save(); | ||
| 96 | + } catch (ErrorException $e) { | ||
| 97 | + CustomVarDamp::dump($e->getMessage()); | ||
| 98 | + } | ||
| 99 | + // получим id только что записанной записи - его запишем в название файла | ||
| 100 | + $model->record_id = $files_model->find() | ||
| 101 | + ->where(['importer_id' => $files_model->importer_id]) | ||
| 102 | + ->orderBy(['id' => SORT_DESC]) | ||
| 103 | + ->one() | ||
| 104 | + ->id; | ||
| 78 | 105 | ||
| 79 | - $model->file->saveAs( $filePath ); | ||
| 80 | - $data = $model->readFile($filePath); | 106 | + $file_name = $model->record_id . '.' . $model->file->extension; |
| 81 | 107 | ||
| 82 | - Yii::$app->getCache()->set( 'parser_data', json_encode($data) ); | 108 | + if ($model->mode) { |
| 109 | + $model->file_path = Yii::getAlias('@auto_upload') . '/' . $file_name; | ||
| 110 | + } else { | ||
| 111 | + $model->file_path = Yii::getAlias('@manual_upload') . '/' . $file_name; | ||
| 112 | + } | ||
| 83 | 113 | ||
| 84 | - } | 114 | + $model->file->saveAs($model->file_path); |
| 85 | 115 | ||
| 86 | - } else if( Yii::$app->getCache()->get( 'parser_data' )) { | 116 | + // для авто загрузки, обработка завершена |
| 117 | + if ($model->mode) { | ||
| 118 | + $model->success = true; | ||
| 119 | + return $this->render('index', ['model' => $model]); | ||
| 120 | + } | ||
| 87 | 121 | ||
| 88 | - $data = json_decode( Yii::$app->getCache()->get( 'parser_data' ),true ); | 122 | + // === ручная загрузка =========== |
| 123 | + //запускаем парсинг | ||
| 124 | + $data = $model->readFile(); | ||
| 125 | + // сохраняем в кеш отпарсенные даные | ||
| 126 | + Yii::$app->getCache()->set('parser_data', json_encode($data)); | ||
| 127 | + // сохраняем в кеш модель - в ней настройки для дальнейшей обработки данных | ||
| 128 | + Yii::$app->getCache()->set('parser_configuration', serialize($model)); | ||
| 129 | + | ||
| 130 | + | ||
| 131 | + } else { | ||
| 132 | + // не прошла валидация форма загрузки файлов | ||
| 133 | + //@todo - отправка на страницу ошибок | ||
| 134 | + $errors_arr = $model->getErrors(); | ||
| 135 | + foreach ($errors_arr as $error) { | ||
| 136 | + CustomVarDamp::dump(array_values($error)); | ||
| 137 | + } | ||
| 138 | + die; | ||
| 139 | + } | ||
| 140 | + // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные | ||
| 141 | + } else if (Yii::$app->getCache()->get('parser_data')) { | ||
| 142 | + | ||
| 143 | + $data = json_decode(Yii::$app->getCache()->get('parser_data'), true); | ||
| 89 | 144 | ||
| 90 | } | 145 | } |
| 91 | 146 | ||
| @@ -96,38 +151,168 @@ class ParserController extends BaseController | @@ -96,38 +151,168 @@ class ParserController extends BaseController | ||
| 96 | ], | 151 | ], |
| 97 | ]); | 152 | ]); |
| 98 | 153 | ||
| 99 | - // CustomVarDamp::dumpAndDie($data); | ||
| 100 | - $header_model = DynamicFormHelper::CreateDynamicModel( count( $data[0] ) ); | 154 | + //формируем заголовок для пользователя, где он сможет выбрать соответсвие полей (выпадающий список) |
| 155 | + $header_model = DynamicFormHelper::CreateDynamicModel(count($data[0])); | ||
| 101 | 156 | ||
| 102 | - // CustomVarDamp::dumpAndDie(Yii::$app->multiparser->getConfiguration('csv','basic_column')); | ||
| 103 | return $this->render('results', | 157 | return $this->render('results', |
| 104 | ['model' => $data, | 158 | ['model' => $data, |
| 105 | 'header_model' => $header_model, | 159 | 'header_model' => $header_model, |
| 106 | - 'basic_column' => Yii::$app->multiparser->getConfiguration('csv','basic_column'), | 160 | + // список колонок для выбора |
| 161 | + 'basic_column' => Yii::$app->multiparser->getConfiguration('csv', 'basic_column'), | ||
| 107 | 'dataProvider' => $provider]); | 162 | 'dataProvider' => $provider]); |
| 108 | } | 163 | } |
| 109 | 164 | ||
| 110 | -public function actionWrite() | ||
| 111 | -{ | ||
| 112 | - //CustomVarDamp::dumpAndDie(Yii::$app->request->post()); | 165 | + public function actionWrite() |
| 166 | + { | ||
| 167 | + //получим колонки которые выбрал пользователь | ||
| 168 | + $arr_attributes = Yii::$app->request->post()['DynamicModel']; | ||
| 169 | + //соберем модель по полученным данным | ||
| 170 | + $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); | ||
| 171 | + //добавим правила валидации (колонки должны быть те что указаны в конфиге) | ||
| 172 | + foreach ($arr_attributes as $key => $value) { | ||
| 173 | + $model->addRule($key, 'in', ['range' => array_keys(Yii::$app->multiparser->getConfiguration('csv', 'basic_column'))]); | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + // провалидируем выбранные колонки | ||
| 177 | + if ($model->validate()) { | ||
| 178 | + | ||
| 179 | + // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы | ||
| 180 | + $arr = $model->toArray(); | ||
| 181 | + | ||
| 182 | + // получим данные из кеша | ||
| 183 | + if (Yii::$app->getCache()->get('parser_data') && Yii::$app->getCache()->get('parser_configuration')) { | ||
| 184 | + $data = json_decode(Yii::$app->getCache()->get('parser_data'), true); | ||
| 185 | + $configuration = unserialize(Yii::$app->getCache()->get('parser_configuration')); | ||
| 186 | + } else { | ||
| 187 | + CustomVarDamp::dumpAndDie('Ошибка кеша'); | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + // соотнесем отпарсенные данные с соответсивем полученным от пользователя | ||
| 191 | + // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию | ||
| 192 | + $data = \Yii::$app->multiparser->convertToAssocArray($data, $arr, 'attr_'); | ||
| 193 | + | ||
| 194 | + | ||
| 195 | + // 1. запишем дату старта в таблицу файлов поставщика (ImportersFiles) | ||
| 196 | + // id загруженного файла получим из конфигурации | ||
| 197 | + $files_model = ImporterFiles::findOne( $configuration->record_id ); | ||
| 198 | + | ||
| 199 | + //$files_model->load(['ImporterFiles' => $configuration->toArray()]); | ||
| 200 | + $update_date = date('Y-m-d H:i:s'); | ||
| 201 | + $files_model->time_start = $update_date; | ||
| 202 | + // запишем дату начала загрузки | ||
| 203 | + if (!$files_model->save()) { | ||
| 204 | + CustomVarDamp::dumpAndDie($files_model->getErrors()); | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + | ||
| 208 | + // 2. запишем полученные данные в таблицу товаров (Details) | ||
| 209 | + $details_model = new Details(); | ||
| 210 | + // проверим все ли обязательные колонки были указаны пользователем | ||
| 211 | + $details_model->load(['Details' => $data[0]]); | ||
| 212 | + if ($details_model->validate()) { | ||
| 213 | + // дополним данные значением импортера и даты обновления цены | ||
| 214 | + $data = \Yii::$app->multiparser->addColumns($data, ['IMPORT_ID' => $configuration->importer_id, 'timestamp' => $update_date]); | ||
| 215 | + | ||
| 216 | + try { | ||
| 217 | + //@todo add transaction | ||
| 218 | + // попытаемся вставить данные в БД с апдейтом по ключам | ||
| 219 | + $details_model->ManualInsert($data); | ||
| 220 | + | ||
| 221 | + // 3. зафиксируем дату конца загрузки в файлах поставщика | ||
| 222 | + | ||
| 223 | + $files_model->time_end = date('Y-m-d H:i:s'); | ||
| 224 | + // CustomVarDamp::dumpAndDie($files_model); | ||
| 225 | + if (!$files_model->save()) { | ||
| 226 | + CustomVarDamp::dumpAndDie($files_model->getErrors()); | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + // 4. зафиксируем дату загрузки в таблице поставщиков | ||
| 230 | + $imp_model = Importer::findOne($configuration['importer_id']); | ||
| 231 | + $imp_model->price_date_update = $update_date; | ||
| 232 | + | ||
| 233 | + if (!$imp_model->save()) { | ||
| 234 | + CustomVarDamp::dumpAndDie($imp_model->getErrors()); | ||
| 235 | + } | ||
| 236 | + $configuration['success'] = true; | ||
| 237 | + // все прошло успешно - очищаем кеш | ||
| 238 | + Yii::$app->getCache()->delete('parser_data'); | ||
| 239 | + Yii::$app->getCache()->delete('parser_configuration'); | ||
| 240 | + | ||
| 241 | + unlink($configuration['file_path']); | ||
| 242 | + return $this->render('index', ['model' => $configuration]); | ||
| 243 | + | ||
| 244 | + } catch (ErrorException $e) { | ||
| 245 | + CustomVarDamp::dump($e->getMessage()); | ||
| 246 | + } | ||
| 247 | + } | ||
| 248 | + if ($details_model->hasErrors()) { | ||
| 249 | + $errors_arr = $details_model->getErrors(); | ||
| 250 | + foreach ($errors_arr as $error) { | ||
| 251 | + CustomVarDamp::dump(array_values($error)); | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + | ||
| 257 | + } | ||
| 113 | 258 | ||
| 114 | - $arr_attributes = Yii::$app->request->post()['DynamicModel']; | ||
| 115 | - $model = DynamicFormHelper::CreateDynamicModel( $arr_attributes ); | ||
| 116 | - foreach ($arr_attributes as $key => $value) { | ||
| 117 | - $model->addRule($key, 'in', ['range' => array_keys( Yii::$app->multiparser->getConfiguration('csv','basic_column') )]); | ||
| 118 | } | 259 | } |
| 119 | 260 | ||
| 120 | - //CustomVarDamp::dumpAndDie($model); | ||
| 121 | - if ($model->validate()) { | ||
| 122 | - $arr = $model->toArray(); | ||
| 123 | - $data = json_decode( Yii::$app->getCache()->get( 'parser_data' ),true ); | 261 | + public function actionAutoUpload() |
| 262 | + { | ||
| 263 | + $query = Importer::find()->where(['active' => true])->orderBy(['price_date_update' => SORT_DESC]); | ||
| 124 | 264 | ||
| 125 | - // CustomVarDamp::dumpAndDie(DynamicFormHelper::CreateAssocArray($data, $arr)); | ||
| 126 | - CustomVarDamp::dumpAndDie($arr); | 265 | + $provider = new ActiveDataProvider([ |
| 266 | + 'query' => $query, | ||
| 267 | + 'pagination' => [ | ||
| 268 | + 'pageSize' => 10, | ||
| 269 | + ], | ||
| 270 | + ]); | ||
| 271 | + return $this->render('check_price', | ||
| 272 | + [ | ||
| 273 | + 'dataProvider' => $provider]); | ||
| 127 | } | 274 | } |
| 128 | 275 | ||
| 276 | + public function actionServerFiles () | ||
| 277 | + { | ||
| 278 | + $arr_id = []; | ||
| 279 | + // получим список файлов которые ожидают к загрузке | ||
| 280 | + foreach (glob(Yii::getAlias('@auto_upload') . '/*') as $server_file) { | ||
| 281 | + $file_id = basename($server_file,".csv"); | ||
| 282 | + $arr_id[] = (int) $file_id; | ||
| 283 | + } | ||
| 129 | 284 | ||
| 285 | + $query = ImporterFiles::find()->where(['in', 'id', $arr_id])->orderBy(['upload_time' => SORT_DESC]); | ||
| 130 | 286 | ||
| 131 | -} | 287 | + $provider = new ActiveDataProvider([ |
| 288 | + 'query' => $query, | ||
| 289 | + 'pagination' => [ | ||
| 290 | + 'pageSize' => 10, | ||
| 291 | + ], | ||
| 292 | + ]); | ||
| 293 | + return $this->render('server-files', | ||
| 294 | + [ | ||
| 295 | + 'dataProvider' => $provider]); | ||
| 296 | + } | ||
| 297 | + | ||
| 298 | + public function actionDelete ($id) | ||
| 299 | + { | ||
| 300 | + if(Yii::$app->request->isAjax){ | ||
| 301 | + CustomVarDamp::dumpAndDie(1); | ||
| 302 | + } | ||
| 303 | + | ||
| 304 | + $files_model = new ImporterFiles(); | ||
| 305 | + try { | ||
| 306 | + | ||
| 307 | + $files_model->delete($id); | ||
| 308 | + unlink(Yii::getAlias('@auto_upload') . '/' . $id . '.csv' ); | ||
| 309 | + | ||
| 310 | + } catch (ErrorException $e) { | ||
| 132 | 311 | ||
| 312 | + CustomVarDamp::dump($e->getMessage()); | ||
| 313 | + | ||
| 314 | + } | ||
| 315 | + | ||
| 316 | + $this->redirect('server-files'); | ||
| 317 | + } | ||
| 133 | } | 318 | } |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace backend\models; | ||
| 4 | + | ||
| 5 | +use Yii; | ||
| 6 | +use backend\components\base\BaseActiveRecord; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * This is the model class for table "{{%details}}". | ||
| 10 | + * | ||
| 11 | + * @property string $ID | ||
| 12 | + * @property string $IMPORT_ID | ||
| 13 | + * @property string $BRAND | ||
| 14 | + * @property string $ARTICLE | ||
| 15 | + * @property string $FULL_ARTICLE | ||
| 16 | + * @property double $PRICE | ||
| 17 | + * @property string $DESCR | ||
| 18 | + * @property string $BOX | ||
| 19 | + * @property string $ADD_BOX | ||
| 20 | + * @property string $GROUP | ||
| 21 | + * @property string $timestamp | ||
| 22 | + */ | ||
| 23 | +class Details extends BaseActiveRecord | ||
| 24 | +{ | ||
| 25 | + const KEY_COLUMN = ['IMPORT_ID','BRAND','ARTICLE']; | ||
| 26 | + const BATCH = 500; | ||
| 27 | + /** | ||
| 28 | + * @inheritdoc | ||
| 29 | + */ | ||
| 30 | + public static function tableName() | ||
| 31 | + { | ||
| 32 | + return '{{%details}}'; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * @inheritdoc | ||
| 37 | + */ | ||
| 38 | + public function rules() | ||
| 39 | + { | ||
| 40 | + return [ | ||
| 41 | + [[ 'BRAND', 'ARTICLE', 'PRICE', 'DESCR', 'BOX'], 'required'], | ||
| 42 | + // [['IMPORT_ID', 'BOX', 'ADD_BOX'], 'integer'], | ||
| 43 | + [['PRICE'], 'number'], | ||
| 44 | + [['timestamp'], 'safe'], | ||
| 45 | + [['BRAND', 'ARTICLE'], 'string', 'max' => 100], | ||
| 46 | + [['FULL_ARTICLE'], 'string', 'max' => 150], | ||
| 47 | + [['DESCR', 'GROUP'], 'string', 'max' => 200] | ||
| 48 | + ]; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * @inheritdoc | ||
| 53 | + */ | ||
| 54 | + public function attributeLabels() | ||
| 55 | + { | ||
| 56 | + return [ | ||
| 57 | + 'ID' => Yii::t('app', 'ID'), | ||
| 58 | + 'IMPORT_ID' => Yii::t('app', 'Import ID'), | ||
| 59 | + 'BRAND' => Yii::t('app', 'Brand'), | ||
| 60 | + 'ARTICLE' => Yii::t('app', 'Article'), | ||
| 61 | + 'FULL_ARTICLE' => Yii::t('app', 'Full Article'), | ||
| 62 | + 'PRICE' => Yii::t('app', 'Price'), | ||
| 63 | + 'DESCR' => Yii::t('app', 'Descr'), | ||
| 64 | + 'BOX' => Yii::t('app', 'Box'), | ||
| 65 | + 'ADD_BOX' => Yii::t('app', 'Add Box'), | ||
| 66 | + 'GROUP' => Yii::t('app', 'Group'), | ||
| 67 | + 'timestamp' => Yii::t('app', 'Timestamp'), | ||
| 68 | + ]; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + public function ManualInsert ($data) | ||
| 72 | + { | ||
| 73 | + // \common\components\CustomVarDamp::dumpAndDie($data); | ||
| 74 | + $table_name = self::tableName(); | ||
| 75 | + $keys_arr = array_keys( $data[0] ); | ||
| 76 | + // найдем те поля которые не являются ключами. Их нужно будет при дубляже апдейтить | ||
| 77 | + $fields_arr_to_update = array_diff( $keys_arr, $this::KEY_COLUMN ); | ||
| 78 | + | ||
| 79 | + $query_update = ' on duplicate key update '; | ||
| 80 | + foreach ($fields_arr_to_update as $field) { | ||
| 81 | + $query_update .= "{$field} = values({$field}),"; | ||
| 82 | + } | ||
| 83 | + // удалим последнюю запятую | ||
| 84 | + $query_update = substr($query_update, 0, strlen($query_update) - 1); | ||
| 85 | + | ||
| 86 | + // запросы будем выполнять пакетами | ||
| 87 | + // размер пакета установлен в константе | ||
| 88 | + // разобъем массив на пакеты и будем их проходить | ||
| 89 | + $data = array_chunk($data, $this::BATCH ); | ||
| 90 | + foreach( $data as $current_batch_array ){ | ||
| 91 | + | ||
| 92 | + //воспользуемся пакетной вставкой от фреймворка, плюс сразу с экранированием и защитой от инъекций | ||
| 93 | + $query_insert = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $current_batch_array)->sql; | ||
| 94 | + // добавим фрагмент с апдейтом при дубляже | ||
| 95 | + $query = "{$query_insert} {$query_update}"; | ||
| 96 | + // \common\components\CustomVarDamp::dumpAndDie($query); | ||
| 97 | + $res = Yii::$app->db->createCommand($query)->execute(); | ||
| 98 | + | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + } | ||
| 102 | +} |
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * Created by PhpStorm. | ||
| 4 | + * User: Cibermag | ||
| 5 | + * Date: 15.09.2015 | ||
| 6 | + * Time: 16:49 | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | +namespace backend\models; | ||
| 10 | + | ||
| 11 | +use yii\base\Model; | ||
| 12 | +use Yii; | ||
| 13 | + | ||
| 14 | +class Details_old extends Model{ | ||
| 15 | + const KEY_COLUMN = ['IMPORT_ID','BRAND','ARTICLE']; | ||
| 16 | + const BATCH = 500; | ||
| 17 | + | ||
| 18 | + private $mode; | ||
| 19 | + | ||
| 20 | + // обязательные поля модели | ||
| 21 | + public $BRAND; | ||
| 22 | + public $ARTICLE; | ||
| 23 | + public $PRICE; | ||
| 24 | + public $BOX; | ||
| 25 | + | ||
| 26 | + function __construct($mode) | ||
| 27 | + { | ||
| 28 | + $this->mode = $mode; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public function rules() | ||
| 32 | + { | ||
| 33 | + return [ | ||
| 34 | + [['BRAND','ARTICLE', 'PRICE', 'BOX'], 'required' ], | ||
| 35 | + ]; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + public function formName() | ||
| 39 | + { | ||
| 40 | + return 'Details'; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + | ||
| 44 | + public static function tableName() | ||
| 45 | + { | ||
| 46 | + return '{{%details}}'; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | +// //@todo вероятно этой функции не место здесь | ||
| 50 | +// public function prepareData ( $data, $configuration ) | ||
| 51 | +// { | ||
| 52 | +// if ( isset($configuration['importer_id']) && $configuration['importer_id']) { | ||
| 53 | +// $data = \Yii::$app->multiparser->addColumn( $data, 'IMPORT_ID', $configuration['importer_id'] ); | ||
| 54 | +// } | ||
| 55 | +// // \common\components\CustomVarDamp::dumpAndDie($data); | ||
| 56 | +// return $data; | ||
| 57 | +// } | ||
| 58 | + | ||
| 59 | + /** | ||
| 60 | + * @param $data - двумерный массив данных для записи в таблицу details | ||
| 61 | + * @throws \yii\db\Exception | ||
| 62 | + * вставляет записи с апдейтом при дубляже ключей | ||
| 63 | + */ | ||
| 64 | + public function save ($data) | ||
| 65 | + { | ||
| 66 | + $table_name = self::tableName(); | ||
| 67 | + $keys_arr = array_keys( $data[0] ); | ||
| 68 | + // найдем те поля которые не являются ключами. Их нужно будет при дубляже апдейтить | ||
| 69 | + $fields_arr_to_update = array_diff( $keys_arr, $this::KEY_COLUMN ); | ||
| 70 | + | ||
| 71 | + $query_update = ' on duplicate key update '; | ||
| 72 | + foreach ($fields_arr_to_update as $field) { | ||
| 73 | + $query_update .= "{$field} = values({$field}),"; | ||
| 74 | + } | ||
| 75 | + // удалим последнюю запятую | ||
| 76 | + $query_update = substr($query_update, 0, strlen($query_update) - 1); | ||
| 77 | + | ||
| 78 | + // запросы будем выполнять пакетами | ||
| 79 | + // размер пакета установлен в константе | ||
| 80 | + // разобъем массив на пакеты и будем их проходить | ||
| 81 | + $data = array_chunk($data, $this::BATCH ); | ||
| 82 | + foreach( $data as $current_batch_array ){ | ||
| 83 | + | ||
| 84 | + //воспользуемся пакетной вставкой от фреймворка, плюс сразу с экранированием и защитой от инъекций | ||
| 85 | + $query_insert = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $current_batch_array)->sql; | ||
| 86 | + // добавим фрагмент с апдейтом при дубляже | ||
| 87 | + $query = "{$query_insert} {$query_update}"; | ||
| 88 | + // \common\components\CustomVarDamp::dumpAndDie($query); | ||
| 89 | + $res = Yii::$app->db->createCommand($query)->execute(); | ||
| 90 | + | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + } | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +// | ||
| 97 | + | ||
| 98 | +//$q = " INSERT INTO {$table_name} ({$keys_string}) VALUES ("; | ||
| 99 | + | ||
| 100 | +//$q .= " on duplicate key update `FULL_ARTICLE` = values (`FULL_ARTICLE`), | ||
| 101 | +// `PRICE` = values (`PRICE`), | ||
| 102 | +// `DESCR` = values(`DESCR`), | ||
| 103 | +// `BOX` = values(`BOX`), | ||
| 104 | +// `ADD_BOX` = values(`ADD_BOX`), | ||
| 105 | +// `GROUP` = values(`GROUP`);"; | ||
| 106 | + | ||
| 107 | +// INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) | ||
| 108 | +// ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b); | ||
| 109 | + | ||
| 110 | + | ||
| 111 | + | ||
| 112 | +//INSERT INTO `books` (`UserId`, `BookId`, `Count`) VALUES (13, 1001, 3) | ||
| 113 | +//ON DUPLICATE KEY UPDATE `Count` = `Count` + VALUES(`Count`); | ||
| 114 | + | ||
| 115 | +//$values_string = ''; | ||
| 116 | +//$keys_arr = array_keys( $data[0] ); | ||
| 117 | +//$keys_string = implode( ',', $keys_arr); | ||
| 118 | +//$table_name = self::tableName(); | ||
| 119 | +//$current_batch = 0; | ||
| 120 | +//for ($i = $current_batch; $i < $this::BATCH AND $i < count($data); $i++) { | ||
| 121 | +// $values_string .= '(' . implode( ',', $data[$i]) . '),'; | ||
| 122 | +//} | ||
| 123 | +// for ($current_batch = $this::BATCH; $current_batch<count($data); $current_batch + $this::BATCH ) | ||
| 124 | +//// удалим последнюю запятую | ||
| 125 | +//$values_string = substr($values_string, 0, strlen($values_string) - 1) . ' '; | ||
| 126 | +////\common\components\CustomVarDamp::dumpAndDie($values_string); | ||
| 127 | +//// $query = "INSERT INTO {$table_name}({$keys_string}) VALUES {$values_string}"; | ||
| 128 | +//// on duplicate key update `PRICE` = values (`PRICE`),`DESCR` = values(`DESCR`),`BOX` = values(`BOX`)"; | ||
| 129 | +//$query_insert = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $data)->sql; | ||
| 130 | +//$query = "{$query_insert} on duplicate key update `PRICE` = values (`PRICE`),`DESCR` = values(`DESCR`),`BOX` = values(`BOX`)"; | ||
| 131 | +//$res = Yii::$app->db->createCommand($query)->execute(); | ||
| 132 | + | ||
| 133 | + | ||
| 134 | + | ||
| 135 | +// Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $data)->sql execute(); | ||
| 0 | \ No newline at end of file | 136 | \ No newline at end of file |
backend/models/Importer.php
| @@ -47,13 +47,14 @@ class Importer extends BaseActiveRecord | @@ -47,13 +47,14 @@ class Importer extends BaseActiveRecord | ||
| 47 | public function rules() | 47 | public function rules() |
| 48 | { | 48 | { |
| 49 | return [ | 49 | return [ |
| 50 | - [['code', 'name', 'name_price', 'currency_id', 'delivery', 'email', 'info', 'PARSER_FIELD_SIGN', 'price_date_update'], 'required'], | 50 | + [['code', 'name', 'currency_id', 'delivery', 'price_date_update'], 'required'], |
| 51 | + [['name_price', 'email', 'PARSER_FIELD_SIGN', 'info'], 'safe'], | ||
| 51 | [['currency_id', 'active', 'PARSER_IS_ACTIVE', 'PARSER_COLUMN_COUNT', 'PARSER_FIELD_BRAND', 'PARSER_FIELD_ARTICLE', 'PARSER_FIELD_ARTICLE_PREFIX', 'PARSER_FIELD_PRICE', 'PARSER_FIELD_DESCR', 'PARSER_FIELD_BOX', 'PARSER_FIELD_ADD_BOX', 'PARSER_FIELD_GROUP_RG'], 'integer'], | 52 | [['currency_id', 'active', 'PARSER_IS_ACTIVE', 'PARSER_COLUMN_COUNT', 'PARSER_FIELD_BRAND', 'PARSER_FIELD_ARTICLE', 'PARSER_FIELD_ARTICLE_PREFIX', 'PARSER_FIELD_PRICE', 'PARSER_FIELD_DESCR', 'PARSER_FIELD_BOX', 'PARSER_FIELD_ADD_BOX', 'PARSER_FIELD_GROUP_RG'], 'integer'], |
| 52 | [['info'], 'string'], | 53 | [['info'], 'string'], |
| 53 | [['PARSER_FIELD_MULTIPLIER'], 'number'], | 54 | [['PARSER_FIELD_MULTIPLIER'], 'number'], |
| 54 | [['code', 'name', 'name_price', 'delivery', 'email'], 'string', 'max' => 254], | 55 | [['code', 'name', 'name_price', 'delivery', 'email'], 'string', 'max' => 254], |
| 55 | [['PARSER_FIELD_SIGN'], 'string', 'max' => 1], | 56 | [['PARSER_FIELD_SIGN'], 'string', 'max' => 1], |
| 56 | - [['price_date_update'], 'string', 'max' => 15], | 57 | + // [['price_date_update'], 'string', 'max' => 15], |
| 57 | [['code'], 'unique'], | 58 | [['code'], 'unique'], |
| 58 | [['name'], 'unique'] | 59 | [['name'], 'unique'] |
| 59 | ]; | 60 | ]; |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace backend\models; | ||
| 4 | + | ||
| 5 | +use common\components\CustomVarDamp; | ||
| 6 | +use Yii; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * This is the model class for table "{{%importer_files}}". | ||
| 10 | + * | ||
| 11 | + * @property integer $id | ||
| 12 | + * @property string $importer_id | ||
| 13 | + * @property string $upload_time | ||
| 14 | + * @property string $time_start | ||
| 15 | + * @property string $time_end | ||
| 16 | + */ | ||
| 17 | +class ImporterFiles extends \yii\db\ActiveRecord | ||
| 18 | +{ | ||
| 19 | + /** | ||
| 20 | + * @inheritdoc | ||
| 21 | + */ | ||
| 22 | + public static function tableName() | ||
| 23 | + { | ||
| 24 | + return '{{%importer_files}}'; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * @inheritdoc | ||
| 29 | + */ | ||
| 30 | + public function rules() | ||
| 31 | + { | ||
| 32 | + return [ | ||
| 33 | + [['importer_id'], 'required'], | ||
| 34 | + [['importer_id'], 'integer'], | ||
| 35 | + [['upload_time', 'time_start', 'time_end'], 'safe'] | ||
| 36 | + ]; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + public function getImporter () | ||
| 40 | + { | ||
| 41 | + return $this->hasOne(Importer::className(), ['id' => 'importer_id'])->one()->name; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * @inheritdoc | ||
| 46 | + */ | ||
| 47 | + public function attributeLabels() | ||
| 48 | + { | ||
| 49 | + return [ | ||
| 50 | + 'id' => Yii::t('app', 'ID'), | ||
| 51 | + 'importer_id' => Yii::t('app', 'Importer ID'), | ||
| 52 | + 'upload_time' => Yii::t('app', 'Upload Time'), | ||
| 53 | + 'time_start' => Yii::t('app', 'Time Start'), | ||
| 54 | + 'time_end' => Yii::t('app', 'Time End'), | ||
| 55 | + ]; | ||
| 56 | + } | ||
| 57 | +} |
backend/models/UploadFileParsingForm.php
| @@ -14,28 +14,48 @@ class UploadFileParsingForm extends Model | @@ -14,28 +14,48 @@ class UploadFileParsingForm extends Model | ||
| 14 | /** | 14 | /** |
| 15 | * @var UploadedFile file attribute | 15 | * @var UploadedFile file attribute |
| 16 | */ | 16 | */ |
| 17 | + // атрибуты формы | ||
| 17 | public $file; | 18 | public $file; |
| 18 | - public $importer; | 19 | + public $importer_id; |
| 19 | public $action; | 20 | public $action; |
| 20 | public $delimiter; | 21 | public $delimiter; |
| 21 | public $delete_price; | 22 | public $delete_price; |
| 22 | public $delete_prefix; | 23 | public $delete_prefix; |
| 23 | 24 | ||
| 25 | + // служебные атрибуты | ||
| 26 | + public $file_path; | ||
| 27 | + public $success; | ||
| 28 | + public $mode; //0 - режим ручной загрузки, 1 - режим автозагрузки | ||
| 29 | + public $record_id; // id таблицы в которую записывается информация о файле | ||
| 30 | + | ||
| 24 | /** | 31 | /** |
| 25 | * @return array the validation rules. | 32 | * @return array the validation rules. |
| 26 | */ | 33 | */ |
| 34 | + public function __construct($config = []) | ||
| 35 | + { | ||
| 36 | + parent::__construct($config); | ||
| 37 | + if ( $this->mode ) { | ||
| 38 | + // автозагрузка, проставим сценарий | ||
| 39 | + $this->scenario = 'auto'; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + | ||
| 27 | public function rules() | 45 | public function rules() |
| 28 | { | 46 | { |
| 29 | return [ | 47 | return [ |
| 30 | - ['importer', 'required', 'message' => 'Не указан поставщик!' ], | 48 | + ['importer_id', 'required', 'message' => 'Не указан поставщик!' ], |
| 31 | ['file', 'required', 'message' => 'Не выбран файл!' ], | 49 | ['file', 'required', 'message' => 'Не выбран файл!' ], |
| 32 | //@todo - not working this file validator!!! - fixed | 50 | //@todo - not working this file validator!!! - fixed |
| 33 | [['file'], 'file'],// 'extensions' => ['csv', 'xml'] ], | 51 | [['file'], 'file'],// 'extensions' => ['csv', 'xml'] ], |
| 34 | // 'wrongMimeType' => 'Указан неподдерживаемый тип файла. Можно выбирать csv, xml файлы.' ], | 52 | // 'wrongMimeType' => 'Указан неподдерживаемый тип файла. Можно выбирать csv, xml файлы.' ], |
| 35 | - ['importer', 'integer','max' => 999999, 'min' => 0 ], | ||
| 36 | - [['action','delete_prefix', 'delete_price'], 'boolean'], | 53 | + ['importer_id', 'integer','max' => 999999, 'min' => 0 ], |
| 54 | + [['action','delete_prefix', 'delete_price', 'success'], 'boolean', 'except' => 'auto' ], // только для ручной загрузки | ||
| 37 | ['delimiter', 'string', 'max' => 1], | 55 | ['delimiter', 'string', 'max' => 1], |
| 38 | - ['delimiter', 'default', 'value' => ';'] | 56 | + [['mode','record_id'], 'safe'], |
| 57 | + ['delimiter', 'default', 'value' => ';'], | ||
| 58 | + [ 'success', 'default', 'value' => false] | ||
| 39 | 59 | ||
| 40 | ]; | 60 | ]; |
| 41 | } | 61 | } |
| @@ -44,17 +64,34 @@ class UploadFileParsingForm extends Model | @@ -44,17 +64,34 @@ class UploadFileParsingForm extends Model | ||
| 44 | { | 64 | { |
| 45 | return [ | 65 | return [ |
| 46 | 'file' => Yii::t('app', 'Источник'), | 66 | 'file' => Yii::t('app', 'Источник'), |
| 47 | - 'importer' => Yii::t('app', 'Поставщик'), | 67 | + 'importer_id' => Yii::t('app', 'Поставщик'), |
| 48 | 'delimiter' => Yii::t('app', 'Разделитель'), | 68 | 'delimiter' => Yii::t('app', 'Разделитель'), |
| 49 | ]; | 69 | ]; |
| 50 | } | 70 | } |
| 51 | 71 | ||
| 52 | - public function readFile($filePath){ | 72 | + public function readFile(){ |
| 53 | 73 | ||
| 54 | - $data = Yii::$app->multiparser->parse($filePath); | 74 | + $data = Yii::$app->multiparser->parse( $this->file_path ); |
| 55 | if( !is_array($data) ){ | 75 | if( !is_array($data) ){ |
| 56 | $data = ['No results']; | 76 | $data = ['No results']; |
| 57 | } | 77 | } |
| 78 | + | ||
| 58 | return $data; | 79 | return $data; |
| 59 | } | 80 | } |
| 81 | + | ||
| 82 | + public function fields() | ||
| 83 | + { | ||
| 84 | + return [ | ||
| 85 | + | ||
| 86 | + 'importer_id', | ||
| 87 | + 'delimiter', | ||
| 88 | + 'delete_price', | ||
| 89 | + 'delete_prefix', | ||
| 90 | + 'file_path', | ||
| 91 | + // id записи таблицы ImportersFiles, | ||
| 92 | + // 'id' => 'record_id', | ||
| 93 | + ]; | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + | ||
| 60 | } | 97 | } |
| 61 | \ No newline at end of file | 98 | \ No newline at end of file |
| 1 | +<?php | ||
| 2 | +use yii\helpers\Html; | ||
| 3 | +use yii\grid\GridView; | ||
| 4 | +use yii\grid\SerialColumn; | ||
| 5 | +use yii\grid\ActionColumn; | ||
| 6 | +use yii\widgets\Pjax; | ||
| 7 | + | ||
| 8 | + | ||
| 9 | +/* @var $this yii\web\View */ | ||
| 10 | +/* @var $searchModel backend\models\CatalogSearch */ | ||
| 11 | +/* @var $dataProvider yii\data\ActiveDataProvider */ | ||
| 12 | + | ||
| 13 | +$this->title = 'Проверка прайсов'; | ||
| 14 | +$this->params['breadcrumbs'][] = $this->title; | ||
| 15 | +?> | ||
| 16 | +<div class="catalog-index"> | ||
| 17 | + | ||
| 18 | + <h1><?= Html::encode($this->title) ?></h1> | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + <?= GridView::widget( ['dataProvider' => $dataProvider, | ||
| 22 | + 'columns' => [['class' => SerialColumn::className()], | ||
| 23 | + [ | ||
| 24 | + 'class' => ActionColumn::className(), | ||
| 25 | + 'template'=>'{view}', | ||
| 26 | + 'contentOptions' => function ($model, $key, $index, $column){ | ||
| 27 | + return ['data' => ['id' => $model->id, 'date' => $model->price_date_update]]; | ||
| 28 | + } | ||
| 29 | + ], | ||
| 30 | + [ | ||
| 31 | + 'label' =>'Поставщик', | ||
| 32 | + 'value' => function ($data) { | ||
| 33 | + return '№ ' .$data->id . ' ' . $data->name; | ||
| 34 | + }, | ||
| 35 | + ], | ||
| 36 | + ['label' =>'Дата обновления', | ||
| 37 | + 'attribute' => 'price_date_update' ], | ||
| 38 | + ['label' => 'Кол-во дней', | ||
| 39 | + 'value' => function ($data) { | ||
| 40 | + $date1 = new DateTime("now"); | ||
| 41 | + $date2 = new DateTime( $data->price_date_update ); | ||
| 42 | + $quo_days = $date2->diff($date1)->format('%R%a'); | ||
| 43 | + // уберем первый символ - там знак "+" | ||
| 44 | + $quo_days = substr( $quo_days, 1, strlen($quo_days) ); | ||
| 45 | + $quo_days = (int) $quo_days; | ||
| 46 | + | ||
| 47 | + if($quo_days > 15) | ||
| 48 | + $quo_days = '>15'; | ||
| 49 | + | ||
| 50 | + return $quo_days; | ||
| 51 | + } | ||
| 52 | + ], | ||
| 53 | + ]] );?> | ||
| 54 | + | ||
| 55 | + | ||
| 56 | + | ||
| 57 | + | ||
| 58 | +</div> | ||
| 0 | \ No newline at end of file | 59 | \ No newline at end of file |
| 1 | +<?php | ||
| 2 | +use yii\helpers\Html; | ||
| 3 | +use yii\grid\GridView; | ||
| 4 | +use yii\grid\SerialColumn; | ||
| 5 | +use yii\bootstrap\Modal; | ||
| 6 | + | ||
| 7 | + | ||
| 8 | +/* @var $this yii\web\View */ | ||
| 9 | +/* @var $searchModel backend\models\CatalogSearch */ | ||
| 10 | +/* @var $dataProvider yii\data\ActiveDataProvider */ | ||
| 11 | + | ||
| 12 | +$this->title = 'Проверка прайсов'; | ||
| 13 | +$this->params['breadcrumbs'][] = $this->title; | ||
| 14 | + | ||
| 15 | +?> | ||
| 16 | +<div class="catalog-index"> | ||
| 17 | + | ||
| 18 | + <h1><?= Html::encode($this->title) ?></h1> | ||
| 19 | + | ||
| 20 | + <?= GridView::widget( ['dataProvider' => $dataProvider, | ||
| 21 | + | ||
| 22 | + ] ); | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + ?> | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | +</div> | ||
| 30 | +<?php | ||
| 31 | + | ||
| 32 | +?> | ||
| 0 | \ No newline at end of file | 33 | \ No newline at end of file |
| 1 | +<?php | ||
| 2 | +use yii\helpers\Html; | ||
| 3 | +use yii\grid\GridView; | ||
| 4 | +use yii\grid\SerialColumn; | ||
| 5 | +use yii\grid\ActionColumn; | ||
| 6 | +use yii\widgets\Pjax; | ||
| 7 | + | ||
| 8 | + | ||
| 9 | +/* @var $this yii\web\View */ | ||
| 10 | +/* @var $searchModel backend\models\CatalogSearch */ | ||
| 11 | +/* @var $dataProvider yii\data\ActiveDataProvider */ | ||
| 12 | + | ||
| 13 | +$this->title = 'Проверка прайсов'; | ||
| 14 | +$this->params['breadcrumbs'][] = $this->title; | ||
| 15 | +?> | ||
| 16 | +<div class="catalog-index"> | ||
| 17 | + | ||
| 18 | + <h1><?= Html::encode($this->title) ?></h1> | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + <?= GridView::widget( ['dataProvider' => $dataProvider, | ||
| 22 | + 'columns' => [['class' => SerialColumn::className()], | ||
| 23 | + [ | ||
| 24 | + 'class' => ActionColumn::className(), | ||
| 25 | + 'template'=>'{view}', | ||
| 26 | + 'contentOptions' => function ($model, $key, $index, $column){ | ||
| 27 | + return ['data' => ['id' => $model->id, 'date' => $model->price_date_update]]; | ||
| 28 | + } | ||
| 29 | + ], | ||
| 30 | + [ | ||
| 31 | + 'label' =>'Поставщик', | ||
| 32 | + 'value' => function ($data) { | ||
| 33 | + return '№ ' .$data->id . ' ' . $data->name; | ||
| 34 | + }, | ||
| 35 | + ], | ||
| 36 | + ['label' =>'Дата обновления', | ||
| 37 | + 'attribute' => 'price_date_update' ], | ||
| 38 | + ['label' => 'Кол-во дней', | ||
| 39 | + 'value' => function ($data) { | ||
| 40 | + $date1 = new DateTime("now"); | ||
| 41 | + $date2 = new DateTime( $data->price_date_update ); | ||
| 42 | + $quo_days = $date2->diff($date1)->format('%R%a'); | ||
| 43 | + // уберем первый символ - там знак "+" | ||
| 44 | + $quo_days = substr( $quo_days, 1, strlen($quo_days) ); | ||
| 45 | + $quo_days = (int) $quo_days; | ||
| 46 | + | ||
| 47 | + if($quo_days > 15) | ||
| 48 | + $quo_days = '>15'; | ||
| 49 | + | ||
| 50 | + return $quo_days; | ||
| 51 | + } | ||
| 52 | + ], | ||
| 53 | + ]] );?> | ||
| 54 | + | ||
| 55 | + | ||
| 56 | + | ||
| 57 | + | ||
| 58 | +</div> | ||
| 0 | \ No newline at end of file | 59 | \ No newline at end of file |
| 1 | +<?php | ||
| 2 | +use yii\helpers\Html; | ||
| 3 | +use yii\grid\GridView; | ||
| 4 | +use yii\grid\SerialColumn; | ||
| 5 | +use yii\bootstrap\Modal; | ||
| 6 | + | ||
| 7 | + | ||
| 8 | +/* @var $this yii\web\View */ | ||
| 9 | +/* @var $searchModel backend\models\CatalogSearch */ | ||
| 10 | +/* @var $dataProvider yii\data\ActiveDataProvider */ | ||
| 11 | + | ||
| 12 | +$this->title = 'Проверка прайсов'; | ||
| 13 | +$this->params['breadcrumbs'][] = $this->title; | ||
| 14 | + | ||
| 15 | +?> | ||
| 16 | +<div class="catalog-index"> | ||
| 17 | + | ||
| 18 | + <h1><?= Html::encode($this->title) ?></h1> | ||
| 19 | + | ||
| 20 | + <?= GridView::widget( ['dataProvider' => $dataProvider, | ||
| 21 | + | ||
| 22 | + ] ); | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + ?> | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | +</div> | ||
| 30 | +<?php | ||
| 31 | + | ||
| 32 | +?> | ||
| 0 | \ No newline at end of file | 33 | \ No newline at end of file |
backend/views/layouts/column.php
| @@ -282,7 +282,13 @@ $this->beginContent('@app/views/layouts/main.php'); | @@ -282,7 +282,13 @@ $this->beginContent('@app/views/layouts/main.php'); | ||
| 282 | echo Menu::widget([ | 282 | echo Menu::widget([ |
| 283 | 'options' => ['class' => 'sidebar-menu'], | 283 | 'options' => ['class' => 'sidebar-menu'], |
| 284 | 'items' => [ | 284 | 'items' => [ |
| 285 | - ['label' => "Прайс парсер", 'url' => ['parser/index']], | 285 | + ['label' => "Загрузка файлов", 'url' => ['#'], 'items' => [ |
| 286 | + ['label' => 'Файлы на сервере', 'url' => ['parser/server-files']], | ||
| 287 | + ['label' => 'Загрузить файл на сервер', 'url' => ['parser/index', 'mode' => 1]], | ||
| 288 | + ['label' => 'Ручная загрузка', 'url' => ['parser/index']], | ||
| 289 | + ['label' => 'Проверка прайс файлов', 'url' => ['check-price/index']], | ||
| 290 | + ], | ||
| 291 | + ], | ||
| 286 | ['label' => 'Управление ролями', 'url' => ['#'], 'items' => [ | 292 | ['label' => 'Управление ролями', 'url' => ['#'], 'items' => [ |
| 287 | ['label' => 'Покупатели', 'url' => '#'], | 293 | ['label' => 'Покупатели', 'url' => '#'], |
| 288 | ['label' => 'Поставщики', 'url' => '#'], | 294 | ['label' => 'Поставщики', 'url' => '#'], |
backend/views/parser/index.php
| @@ -3,29 +3,50 @@ use yii\widgets\ActiveForm; | @@ -3,29 +3,50 @@ use yii\widgets\ActiveForm; | ||
| 3 | use yii\helpers\Html; | 3 | use yii\helpers\Html; |
| 4 | use backend\models\Importer; | 4 | use backend\models\Importer; |
| 5 | use yii\helpers\ArrayHelper; | 5 | use yii\helpers\ArrayHelper; |
| 6 | +if ( $model->mode ) { | ||
| 7 | + // авто загрузка | ||
| 8 | + $mode = 1; | ||
| 9 | + $button_label = 'Загрузить'; | ||
| 10 | +} else { | ||
| 11 | + // ручная загрузка | ||
| 12 | + $mode = 0; | ||
| 13 | + $button_label = 'Прочитать'; | ||
| 14 | +} | ||
| 6 | 15 | ||
| 7 | ?> | 16 | ?> |
| 8 | <div class="row"> | 17 | <div class="row"> |
| 9 | <div class="col-lg-5"> | 18 | <div class="col-lg-5"> |
| 10 | - <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data',],'action'=>['parser/results']]); | 19 | + <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data',],'action'=>['parser/results', 'mode' => $mode]]); |
| 11 | if (!$model->action) { | 20 | if (!$model->action) { |
| 12 | $model->action = 1; | 21 | $model->action = 1; |
| 13 | } | 22 | } |
| 23 | + if ($model->success) { // вернулись после успешной загрузки данного файла | ||
| 24 | + echo Html::tag('h3', 'Файл успешно загружен',['class'=>'bg-success']); | ||
| 25 | + } | ||
| 14 | ?> | 26 | ?> |
| 15 | <h3>Загрузка прайсов поставщиков</h3> | 27 | <h3>Загрузка прайсов поставщиков</h3> |
| 16 | 28 | ||
| 17 | 29 | ||
| 18 | - <?= $form->field($model, 'importer')->dropDownList(ArrayHelper::map( Importer::find()->all(), 'id','name' )); ?> | ||
| 19 | - <?= $form->field($model, 'delete_price')->checkbox(['label' => 'Загрузить с удалением старого прайса']) ?> | 30 | + <?= $form->field($model, 'importer_id')->dropDownList(ArrayHelper::map( Importer::find()->all(), 'id','name' )); ?> |
| 31 | + | ||
| 32 | + <?php if ( !$mode ) { | ||
| 33 | + echo $form->field($model, 'delete_price')->checkbox(['label' => 'Загрузить с удалением старого прайса']); | ||
| 34 | + } | ||
| 35 | + ?> | ||
| 36 | + | ||
| 20 | <?= $form->field($model, 'file')->fileInput()->label(false) ?> | 37 | <?= $form->field($model, 'file')->fileInput()->label(false) ?> |
| 21 | - <?= $form->field($model, 'action')->radioList([1 => 'Стандартная обработка', 0 => 'С разделителем'])->label(false) ?> | ||
| 22 | - <?= $form->field($model, 'delimiter', ['inputOptions' => ['value' => ';']]) ?> | ||
| 23 | 38 | ||
| 24 | - <?= $form->field($model, 'delete_prefix')->checkbox(['label' => 'Удалять префикс']) ?> | 39 | + <?php if ( !$mode ) { |
| 40 | + echo $form->field($model, 'action')->radioList([1 => 'Стандартная обработка', 0 => 'С разделителем'])->label(false); | ||
| 41 | + echo $form->field($model, 'delimiter', ['inputOptions' => ['value' => ';']]); | ||
| 42 | + | ||
| 43 | + echo $form->field($model, 'delete_prefix')->checkbox(['label' => 'Удалять префикс']); | ||
| 44 | + } | ||
| 45 | + ?> | ||
| 25 | 46 | ||
| 26 | 47 | ||
| 27 | <div class="form-group"> | 48 | <div class="form-group"> |
| 28 | - <?= Html::submitButton(Yii::t('app', 'Прочитать'), ['class' => 'btn btn-primary']) ?> | 49 | + <?= Html::submitButton(Yii::t( 'app', $button_label ), ['class' => 'btn btn-primary']) ?> |
| 29 | </div> | 50 | </div> |
| 30 | 51 | ||
| 31 | <?php ActiveForm::end() ?> | 52 | <?php ActiveForm::end() ?> |
| 1 | +<?php | ||
| 2 | +use yii\helpers\Html; | ||
| 3 | +use yii\grid\GridView; | ||
| 4 | +use yii\grid\SerialColumn; | ||
| 5 | +use yii\grid\ActionColumn; | ||
| 6 | +use yii\widgets\Pjax; | ||
| 7 | + | ||
| 8 | + | ||
| 9 | +/* @var $this yii\web\View */ | ||
| 10 | +/* @var $searchModel backend\models\CatalogSearch */ | ||
| 11 | +/* @var $dataProvider yii\data\ActiveDataProvider */ | ||
| 12 | + | ||
| 13 | +$this->title = 'Проверка прайсов'; | ||
| 14 | +$this->params['breadcrumbs'][] = $this->title; | ||
| 15 | +Pjax::begin(); | ||
| 16 | + | ||
| 17 | +?> | ||
| 18 | + <div class="catalog-index"> | ||
| 19 | + | ||
| 20 | + <h1><?= Html::encode($this->title) ?></h1> | ||
| 21 | + | ||
| 22 | + <?= GridView::widget( ['dataProvider' => $dataProvider, | ||
| 23 | + 'columns' => [['class' => SerialColumn::className()], | ||
| 24 | + [ | ||
| 25 | + 'label' =>'Поставщик', | ||
| 26 | + 'value' => function ($data) { | ||
| 27 | + return $data->importer; | ||
| 28 | + }, | ||
| 29 | + ], | ||
| 30 | + ['label' =>'Дата загрузки', | ||
| 31 | + 'attribute' => 'upload_time' ], | ||
| 32 | + | ||
| 33 | + ['class' => ActionColumn::className(), | ||
| 34 | + 'template'=>'{delete}', | ||
| 35 | + 'buttons' => [ | ||
| 36 | + 'delete' => function ($url, $model, $key) { | ||
| 37 | + return Html::a('<span class="glyphicon glyphicon-remove"></span>', $url, [ | ||
| 38 | + 'title' => Yii::t('yii', 'Удалить файл'), | ||
| 39 | + 'data-confirm' => 'Вы уверены что хотите удалить этот файл?', | ||
| 40 | + 'data-method' => 'post', | ||
| 41 | + 'data-pjax' => '1', | ||
| 42 | + ]); | ||
| 43 | + }, | ||
| 44 | + ], | ||
| 45 | + ] | ||
| 46 | + | ||
| 47 | + ]] );?> | ||
| 48 | + | ||
| 49 | + | ||
| 50 | + | ||
| 51 | + </div> | ||
| 52 | +<?php | ||
| 53 | +Pjax::end(); | ||
| 54 | +?> | ||
| 0 | \ No newline at end of file | 55 | \ No newline at end of file |
common/config/bootstrap.php
| @@ -3,3 +3,5 @@ Yii::setAlias('common', dirname(__DIR__)); | @@ -3,3 +3,5 @@ Yii::setAlias('common', dirname(__DIR__)); | ||
| 3 | Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend'); | 3 | Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend'); |
| 4 | Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend'); | 4 | Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend'); |
| 5 | Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console'); | 5 | Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console'); |
| 6 | +Yii::setAlias('auto_upload', dirname(dirname(__DIR__)) . '/backend/uploads/auto'); | ||
| 7 | +Yii::setAlias('manual_upload', dirname(dirname(__DIR__)) . '/backend/uploads/manual'); |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\db\Schema; | ||
| 4 | +use yii\db\Migration; | ||
| 5 | + | ||
| 6 | +class m150915_125129_addDetails extends Migration | ||
| 7 | +{ | ||
| 8 | + public function up() | ||
| 9 | + { | ||
| 10 | + $this->execute('CREATE TABLE `details` ( | ||
| 11 | + `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, | ||
| 12 | + `IMPORT_ID` int(6) unsigned NOT NULL, | ||
| 13 | + `BRAND` varchar(100) NOT NULL, | ||
| 14 | + `ARTICLE` varchar(100) NOT NULL, | ||
| 15 | + `FULL_ARTICLE` varchar(150) NOT NULL, | ||
| 16 | + `PRICE` float(15,2) unsigned NOT NULL, | ||
| 17 | + `DESCR` varchar(200) NOT NULL, | ||
| 18 | + `BOX` int(6) unsigned NOT NULL, | ||
| 19 | + `ADD_BOX` int(6) unsigned NOT NULL DEFAULT 0, | ||
| 20 | + `GROUP` varchar(200) NOT NULL DEFAULT \'\', | ||
| 21 | + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| 22 | + PRIMARY KEY (`ARTICLE`,`BRAND`,`IMPORT_ID`), | ||
| 23 | + UNIQUE KEY `ID_delete` (`ID`), | ||
| 24 | + KEY `timestamp` (`timestamp`), | ||
| 25 | + KEY `ARTICLE` (`ARTICLE`,`BRAND`,`BOX`), | ||
| 26 | + KEY `BRAND` (`BRAND`,`ARTICLE`), | ||
| 27 | + KEY `ARTICLE_2` (`ARTICLE`,`BRAND`,`ADD_BOX`), | ||
| 28 | + KEY `IMPORT_ID` (`IMPORT_ID`,`ARTICLE`), | ||
| 29 | + KEY `IMPORT_ID_2` (`IMPORT_ID`,`timestamp`) | ||
| 30 | + ) ENGINE=InnoDB DEFAULT CHARSET=utf8'); | ||
| 31 | + | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public function down() | ||
| 35 | + { | ||
| 36 | + $this->dropTable('{{%details}}'); | ||
| 37 | + | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | +} |
console/migrations/m150922_094313_change_key_ImportFiles.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\db\Schema; | ||
| 4 | +use yii\db\Migration; | ||
| 5 | + | ||
| 6 | +class m150922_094313_change_key_ImportFiles extends Migration | ||
| 7 | +{ | ||
| 8 | + //@todo вероятно что эта миграция ненужна - посмотреть ближе к концу проекта на ключи которые используются - остальные удалить. | ||
| 9 | + public function up() | ||
| 10 | + { | ||
| 11 | + $this->dropIndex('importer_id', '{{%importer_files}}'); | ||
| 12 | + $this->createIndex('importer_id', '{{%importer_files}}', 'importer_id, upload_time', false); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + public function down() | ||
| 16 | + { | ||
| 17 | + $this->dropIndex('importer_id', '{{%importer_files}}'); | ||
| 18 | + $this->createIndex('importer_id', '{{%importer_files}}', 'importer_id, time_start', false); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +} |
console/migrations/m150922_144040_change_Importer_dataPrice.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\db\Schema; | ||
| 4 | +use yii\db\Migration; | ||
| 5 | + | ||
| 6 | +class m150922_144040_change_Importer_dataPrice extends Migration | ||
| 7 | +{ | ||
| 8 | + public function up() | ||
| 9 | + { | ||
| 10 | + $this->alterColumn('{{%importer}}','price_date_update','TIMESTAMP' ); | ||
| 11 | + $this->createIndex('price_date', '{{%importer}}', 'price_date_update', false); | ||
| 12 | + } | ||
| 13 | + | ||
| 14 | + public function down() | ||
| 15 | + { | ||
| 16 | + $this->alterColumn('{{%importer}}','price_date','varchar(15)' ); | ||
| 17 | + $this->dropIndex('price_date', '{{%importer}}'); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +} |
console/migrations/m150925_111922_add_foreign_key_ImportFiles.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use yii\db\Schema; | ||
| 4 | +use yii\db\Migration; | ||
| 5 | + | ||
| 6 | +class m150925_111922_add_foreign_key_ImportFiles extends Migration | ||
| 7 | +{ | ||
| 8 | + public function up() | ||
| 9 | + { | ||
| 10 | + $this->addForeignKey('importer_fk', '{{%importer_files}}', 'importer_id', '{{%importer}}', 'id'); | ||
| 11 | + } | ||
| 12 | + | ||
| 13 | + public function down() | ||
| 14 | + { | ||
| 15 | + $this->dropForeignKey('importer_fk', '{{%importer_files}}'); | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | +} |
vendor/yiisoft/multiparser/Converter.php
| @@ -7,18 +7,19 @@ | @@ -7,18 +7,19 @@ | ||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | namespace yii\multiparser; | 9 | namespace yii\multiparser; |
| 10 | +use common\components\CustomVarDamp; | ||
| 11 | +use yii\base\Behavior; | ||
| 10 | 12 | ||
| 11 | // класс который содержит преобразователи значений (фильтры) используемые при парсинге | 13 | // класс который содержит преобразователи значений (фильтры) используемые при парсинге |
| 12 | -class Converter | 14 | +class Converter extends Behavior |
| 13 | { | 15 | { |
| 14 | 16 | ||
| 15 | const METHOD_PREFIX = 'convertTo'; | 17 | const METHOD_PREFIX = 'convertTo'; |
| 16 | 18 | ||
| 17 | - public $configuration = []; | 19 | + //public $configuration = []; |
| 18 | 20 | ||
| 19 | - protected static function convertToFloat($value) | 21 | + public static function convertToFloat($value) |
| 20 | { | 22 | { |
| 21 | - | ||
| 22 | if ($value == '') { | 23 | if ($value == '') { |
| 23 | $value = 0; | 24 | $value = 0; |
| 24 | } | 25 | } |
| @@ -33,7 +34,7 @@ class Converter | @@ -33,7 +34,7 @@ class Converter | ||
| 33 | return $value; | 34 | return $value; |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | - protected static function convertToInteger($value) | 37 | + public static function convertToInteger($value) |
| 37 | { | 38 | { |
| 38 | if ($value == '') { | 39 | if ($value == '') { |
| 39 | $value = 0; | 40 | $value = 0; |
| @@ -48,9 +49,8 @@ class Converter | @@ -48,9 +49,8 @@ class Converter | ||
| 48 | return $value; | 49 | return $value; |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | - protected static function convertToString($value) | 52 | + public static function convertToString($value) |
| 52 | { | 53 | { |
| 53 | - | ||
| 54 | $res = ''; | 54 | $res = ''; |
| 55 | if (is_array($value)) { | 55 | if (is_array($value)) { |
| 56 | 56 | ||
| @@ -61,26 +61,9 @@ class Converter | @@ -61,26 +61,9 @@ class Converter | ||
| 61 | $res = Encoder::encodeString($value); | 61 | $res = Encoder::encodeString($value); |
| 62 | 62 | ||
| 63 | } | 63 | } |
| 64 | - | ||
| 65 | return $res; | 64 | return $res; |
| 66 | } | 65 | } |
| 67 | 66 | ||
| 68 | -// protected static function convertToAssocArray($arr) | ||
| 69 | -// { | ||
| 70 | -// | ||
| 71 | -// $res = ''; | ||
| 72 | -// if (is_array($value)) { | ||
| 73 | -// | ||
| 74 | -// $res = Encoder::encodeArray($value); | ||
| 75 | -// | ||
| 76 | -// }elseif ( is_string($value) ) { | ||
| 77 | -// | ||
| 78 | -// $res = Encoder::encodeString($value); | ||
| 79 | -// | ||
| 80 | -// } | ||
| 81 | -// | ||
| 82 | -// return $res; | ||
| 83 | -// } | ||
| 84 | 67 | ||
| 85 | /** | 68 | /** |
| 86 | * @param $name - имя метода конвертации | 69 | * @param $name - имя метода конвертации |
| @@ -90,9 +73,9 @@ class Converter | @@ -90,9 +73,9 @@ class Converter | ||
| 90 | public static function __callStatic( $name, $value ) | 73 | public static function __callStatic( $name, $value ) |
| 91 | { | 74 | { |
| 92 | $method_name = self::METHOD_PREFIX . $name; | 75 | $method_name = self::METHOD_PREFIX . $name; |
| 93 | - if ( method_exists( self::class ,$method_name ) ) { | ||
| 94 | 76 | ||
| 95 | - return self::$method_name( $value[0] ); | 77 | + if ( method_exists( static::class, $method_name ) ) { |
| 78 | + return static::$method_name( $value[0] ); | ||
| 96 | 79 | ||
| 97 | } else{ | 80 | } else{ |
| 98 | // если такого метода конвертации не предусмотрено, то возвращаем не конвертируя | 81 | // если такого метода конвертации не предусмотрено, то возвращаем не конвертируя |
| @@ -101,26 +84,39 @@ class Converter | @@ -101,26 +84,39 @@ class Converter | ||
| 101 | } | 84 | } |
| 102 | } | 85 | } |
| 103 | 86 | ||
| 87 | + public function __call($name, $params) | ||
| 88 | + { | ||
| 89 | + return self::__callStatic( $name, $params ); | ||
| 90 | + } | ||
| 91 | + | ||
| 104 | 92 | ||
| 105 | /** | 93 | /** |
| 106 | - * @param $arr - массив | 94 | + * @param $arr - массив для конвертирования |
| 95 | + * @param $configuration - массив конфигурация конвертирования | ||
| 107 | * @return mixed | 96 | * @return mixed |
| 108 | * конвертирует массив по полученным настройкам, вызывая последовательно функции конвертации (указанные в конфигурации) | 97 | * конвертирует массив по полученным настройкам, вызывая последовательно функции конвертации (указанные в конфигурации) |
| 109 | */ | 98 | */ |
| 110 | - public function convertByConfiguration( $arr ) | 99 | + public static function convertByConfiguration( $arr, $configuration ) |
| 111 | { | 100 | { |
| 112 | $result = $arr; | 101 | $result = $arr; |
| 113 | - | ||
| 114 | - $hasKey = isset( $this->configuration['hasKey'] ); | ||
| 115 | - foreach ( $this->configuration as $key => $value ) { | ||
| 116 | - | 102 | + // \common\components\CustomVarDamp::dumpAndDie( $result ); |
| 103 | + $hasKey = isset( $configuration['hasKey'] ); | ||
| 104 | + foreach ( $configuration['configuration'] as $key => $value ) { | ||
| 105 | + CustomVarDamp::dump($key); | ||
| 117 | if ( $hasKey ){ | 106 | if ( $hasKey ){ |
| 118 | // у нас ассоциативный массив, и мы можем конвертировать каждое значение в отдельности | 107 | // у нас ассоциативный массив, и мы можем конвертировать каждое значение в отдельности |
| 119 | if ( is_array( $value ) ) { | 108 | if ( is_array( $value ) ) { |
| 109 | + //если пустой массив то конвертируем всю строку | ||
| 110 | + if (count( $value ) === 0 ){ | ||
| 111 | + | ||
| 112 | + $result = self::$key( $arr ); | ||
| 113 | + continue; | ||
| 114 | + } | ||
| 115 | + // иначе конвертируем каждую ячейку в отдельности | ||
| 120 | foreach ($value as $sub_value) { | 116 | foreach ($value as $sub_value) { |
| 121 | if (isset($arr[$sub_value])) { | 117 | if (isset($arr[$sub_value])) { |
| 122 | // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле | 118 | // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле |
| 123 | - $result[$arr[$sub_value]] = self::$key( $arr[$sub_value] ); | 119 | + $result[$sub_value] = self::$key( $arr[$sub_value] ); |
| 124 | } | 120 | } |
| 125 | 121 | ||
| 126 | } | 122 | } |
| @@ -128,7 +124,7 @@ class Converter | @@ -128,7 +124,7 @@ class Converter | ||
| 128 | 124 | ||
| 129 | if (isset($arr[$value])) { | 125 | if (isset($arr[$value])) { |
| 130 | // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле | 126 | // конвертируем только те ячейки которые сопоставлены в прочитанном массиве с колонками в конфигурационном файле |
| 131 | - $result[$arr[$value]] = self::$key( $arr[$value] ); | 127 | + $result[$value] = self::$key( $arr[$value] ); |
| 132 | } | 128 | } |
| 133 | 129 | ||
| 134 | } | 130 | } |
vendor/yiisoft/multiparser/CsvParser.php
| @@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
| 3 | 3 | ||
| 4 | */ | 4 | */ |
| 5 | namespace yii\multiparser; | 5 | namespace yii\multiparser; |
| 6 | +use common\components\CustomVarDamp; | ||
| 6 | 7 | ||
| 7 | 8 | ||
| 8 | /** | 9 | /** |
| @@ -78,7 +79,7 @@ class CsvParser implements ParserInterface | @@ -78,7 +79,7 @@ class CsvParser implements ParserInterface | ||
| 78 | // если у файла есть заголовок, то в результате имеем ассоциативный массив | 79 | // если у файла есть заголовок, то в результате имеем ассоциативный массив |
| 79 | $this->converter_conf['hasKey'] = 1; | 80 | $this->converter_conf['hasKey'] = 1; |
| 80 | } | 81 | } |
| 81 | - $this->converter->configuration = $this->converter_conf; | 82 | + //$this->converter->configuration = $this->converter_conf; |
| 82 | 83 | ||
| 83 | } | 84 | } |
| 84 | } | 85 | } |
| @@ -97,7 +98,7 @@ class CsvParser implements ParserInterface | @@ -97,7 +98,7 @@ class CsvParser implements ParserInterface | ||
| 97 | 98 | ||
| 98 | while (!$finish) { | 99 | while (!$finish) { |
| 99 | $j = 0; | 100 | $j = 0; |
| 100 | - $row = $this->readRow(); | 101 | + $row = $this->file->fgetcsv();; |
| 101 | if ($row === false) { | 102 | if ($row === false) { |
| 102 | continue; | 103 | continue; |
| 103 | } | 104 | } |
| @@ -125,30 +126,33 @@ class CsvParser implements ParserInterface | @@ -125,30 +126,33 @@ class CsvParser implements ParserInterface | ||
| 125 | $return = []; | 126 | $return = []; |
| 126 | 127 | ||
| 127 | $current_line = 0; | 128 | $current_line = 0; |
| 128 | - //$this->keys = NULL; | 129 | + // будем считать количество пустых строк подряд - при трех подряд - считаем что это конец файла и выходим |
| 130 | + $empty_lines = 0; | ||
| 131 | + while ( $empty_lines < 3 ) { | ||
| 132 | + // прочтем строку из файла. Если там есть значения - то в ней массив, иначе - false | ||
| 133 | + $row = $this->readRow( $current_line ); | ||
| 129 | 134 | ||
| 130 | - while (($row = $this->readRow()) !== FALSE) { | 135 | + if ($row === false) { |
| 136 | + //счетчик пустых строк | ||
| 137 | + $empty_lines++; | ||
| 138 | + continue; | ||
| 139 | + } | ||
| 140 | + // строка не пустая, имеем прочитанный массив значений | ||
| 131 | $current_line++; | 141 | $current_line++; |
| 132 | if ($this->hasHeaderRow) { | 142 | if ($this->hasHeaderRow) { |
| 143 | + // в файле есть заголовок, но он еще не назначен, назначим | ||
| 133 | if ($this->keys === NULL) { | 144 | if ($this->keys === NULL) { |
| 134 | $this->keys = array_values($row); | 145 | $this->keys = array_values($row); |
| 135 | - } else { | ||
| 136 | - | ||
| 137 | - if (count($this->keys) !== count($row)) { | ||
| 138 | -// | ||
| 139 | - throw new \ErrorException("Invalid columns detected on line # {$current_line}", 0, 1, $this->file->getBasename(), $current_line); | ||
| 140 | - } | ||
| 141 | - | ||
| 142 | - $return[] = array_combine($this->keys, $row); | ||
| 143 | } | 146 | } |
| 144 | - } else { | ||
| 145 | - $return[] = $row; | ||
| 146 | } | 147 | } |
| 147 | // если у нас установлен лимит, при его достижении прекращаем парсинг | 148 | // если у нас установлен лимит, при его достижении прекращаем парсинг |
| 148 | if (($this->last_line) && ($current_line > $this->last_line)) { | 149 | if (($this->last_line) && ($current_line > $this->last_line)) { |
| 149 | break; | 150 | break; |
| 150 | } | 151 | } |
| 152 | + // обнуляем счетчик, так как считаюся пустые строки ПОДРЯД | ||
| 153 | + $empty_lines = 0; | ||
| 151 | 154 | ||
| 155 | + $return[] = $row; | ||
| 152 | } | 156 | } |
| 153 | 157 | ||
| 154 | $this->closeHandler(); | 158 | $this->closeHandler(); |
| @@ -164,16 +168,24 @@ class CsvParser implements ParserInterface | @@ -164,16 +168,24 @@ class CsvParser implements ParserInterface | ||
| 164 | /** | 168 | /** |
| 165 | * @return array - одномерный массив результата парсинга строки | 169 | * @return array - одномерный массив результата парсинга строки |
| 166 | */ | 170 | */ |
| 167 | - protected function readRow() | 171 | + protected function readRow( $current_line ) |
| 168 | { | 172 | { |
| 169 | - | ||
| 170 | $row = $this->file->fgetcsv(); | 173 | $row = $this->file->fgetcsv(); |
| 171 | if (is_array($row)) { | 174 | if (is_array($row)) { |
| 172 | - // попытаемся конвертировать прочитанные занчения согдасно конфигурации котнвертера значений | ||
| 173 | - // \common\components\CustomVarDamp::dump($row,1); | 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 | + // попытаемся конвертировать прочитанные значения согласно конфигурации котнвертера значений | ||
| 174 | $row = $this->convert($row); | 186 | $row = $this->convert($row); |
| 175 | - // \common\components\CustomVarDamp::dump($row,2); | ||
| 176 | - if ($this->first_column) { | 187 | + // обрежем массив к первой значимой колонке |
| 188 | + if ( $this->first_column ) { | ||
| 177 | 189 | ||
| 178 | $row = array_slice($row, $this->first_column); | 190 | $row = array_slice($row, $this->first_column); |
| 179 | 191 | ||
| @@ -198,7 +210,7 @@ class CsvParser implements ParserInterface | @@ -198,7 +210,7 @@ class CsvParser implements ParserInterface | ||
| 198 | 210 | ||
| 199 | if (!is_null($converter)) { | 211 | if (!is_null($converter)) { |
| 200 | 212 | ||
| 201 | - $result = $converter->convertByConfiguration( $arr ); | 213 | + $result = $converter->convertByConfiguration( $arr, $this->converter_conf ); |
| 202 | 214 | ||
| 203 | } | 215 | } |
| 204 | 216 |
vendor/yiisoft/multiparser/DynamicFormHelper.php
| @@ -22,7 +22,6 @@ class DynamicFormHelper | @@ -22,7 +22,6 @@ class DynamicFormHelper | ||
| 22 | { | 22 | { |
| 23 | 23 | ||
| 24 | const KEY_PREFIX = 'attr_'; | 24 | const KEY_PREFIX = 'attr_'; |
| 25 | - private static $key_array; | ||
| 26 | 25 | ||
| 27 | /** | 26 | /** |
| 28 | * @param $source - int or array | 27 | * @param $source - int or array |
| @@ -68,36 +67,4 @@ class DynamicFormHelper | @@ -68,36 +67,4 @@ class DynamicFormHelper | ||
| 68 | 67 | ||
| 69 | } | 68 | } |
| 70 | 69 | ||
| 71 | - /** | ||
| 72 | - * @param $value_arr - двумерный массив значений, которому нужно присвоить ключи | ||
| 73 | - * @param $key_array - ключи для вложенного массива | ||
| 74 | - * @return array - таблица с проименованными колонками | ||
| 75 | - */ | ||
| 76 | - public static function CreateAssocArray ($value_arr, $key_array) | ||
| 77 | - { | ||
| 78 | - // преобразуем массив ключей (обернем в массив), для передачи его в качестве параметра в анонимную функцию для array_map | ||
| 79 | - // для этого увеличим размерность массива, что бы при каждом обходе массива $value_arr , функции был доступен исходный массив ключей | ||
| 80 | - $key_array = array_fill( 0, count($value_arr), array_flip($key_array)); | ||
| 81 | - | ||
| 82 | - $result = array_map( | ||
| 83 | - function ($value, $key_array) { | ||
| 84 | - $res = $value; | ||
| 85 | - foreach ($value as $key => $sub_value) { | ||
| 86 | - if (isset($key_array[$key])) { | ||
| 87 | - // если такой ключ в базовом массиве (массиве ключей) есть, то заменим новым, иначе просто удалим | ||
| 88 | - $new_key = $key_array[$key]; | ||
| 89 | - if( !array_key_exists( $new_key , $res ) ){ | ||
| 90 | - $res[ $new_key ] = $res[$key]; | ||
| 91 | - } | ||
| 92 | - } | ||
| 93 | - unset( $res[$key] ); | ||
| 94 | - } | ||
| 95 | - | ||
| 96 | - return $res; | ||
| 97 | - }, | ||
| 98 | - $value_arr, $key_array); | ||
| 99 | - return $result; | ||
| 100 | - } | ||
| 101 | - | ||
| 102 | - | ||
| 103 | } | 70 | } |
| 104 | \ No newline at end of file | 71 | \ No newline at end of file |
vendor/yiisoft/multiparser/XmlParser.php
| @@ -22,8 +22,7 @@ class XmlParser implements ParserInterface{ | @@ -22,8 +22,7 @@ class XmlParser implements ParserInterface{ | ||
| 22 | $result = $result[$this->node]; | 22 | $result = $result[$this->node]; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | - //\common\components\CustomVarDamp::dumpAndDie($result); | ||
| 26 | - $result = DynamicFormHelper::CreateAssocArray($result, \Yii::$app->multiparser->getConfiguration('xml','basic_column')); | 25 | + DynamicFormHelper::CreateAssocArray($result, \Yii::$app->multiparser->getConfiguration('xml','basic_column')); |
| 27 | \common\components\CustomVarDamp::dumpAndDie($result); | 26 | \common\components\CustomVarDamp::dumpAndDie($result); |
| 28 | } | 27 | } |
| 29 | 28 |
vendor/yiisoft/multiparser/YiiMultiparser.php
| @@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
| 8 | 8 | ||
| 9 | namespace yii\multiparser; | 9 | namespace yii\multiparser; |
| 10 | 10 | ||
| 11 | +use common\components\CustomVarDamp; | ||
| 11 | use yii\base\Component; | 12 | use yii\base\Component; |
| 12 | 13 | ||
| 13 | 14 | ||
| @@ -38,4 +39,5 @@ public $configuration; | @@ -38,4 +39,5 @@ public $configuration; | ||
| 38 | 39 | ||
| 39 | } | 40 | } |
| 40 | 41 | ||
| 42 | + | ||
| 41 | } | 43 | } |
| 42 | \ No newline at end of file | 44 | \ No newline at end of file |