Commit 8894c93a4170eaa5022ae68411aa24e20e365ba6
1 parent
28253169
add Importers files AR, make write procedure to Details
Showing
10 changed files
with
337 additions
and
107 deletions
Show diff stats
backend/components/parsers/CustomConverter.php
@@ -11,15 +11,19 @@ class CustomConverter extends Converter { | @@ -11,15 +11,19 @@ class CustomConverter extends Converter { | ||
11 | */ | 11 | */ |
12 | public static function convertToAssocArray ($value_arr, $key_array, $key_prefix = '') | 12 | public static function convertToAssocArray ($value_arr, $key_array, $key_prefix = '') |
13 | { | 13 | { |
14 | + // очистка служебного префикса в массиве заголовков | ||
14 | if ($key_prefix) { | 15 | if ($key_prefix) { |
15 | - $parametrs_array = array_fill( 0, count($key_array), $key_prefix ); | ||
16 | - $key_array = array_map( function ($value, $key_prefix){ return str_replace( $key_prefix, '',$value ); }, $key_array, $parametrs_array ); | 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 !==''; }); | ||
17 | } | 21 | } |
18 | 22 | ||
19 | // преобразуем массив ключей (обернем в массив), для передачи его в качестве параметра в анонимную функцию для array_map | 23 | // преобразуем массив ключей (обернем в массив), для передачи его в качестве параметра в анонимную функцию для array_map |
20 | // для этого увеличим размерность массива, что бы при каждом обходе массива $value_arr , функции был доступен исходный массив ключей | 24 | // для этого увеличим размерность массива, что бы при каждом обходе массива $value_arr , функции был доступен исходный массив ключей |
21 | $key_array = array_fill( 0, count($value_arr), $key_array ); | 25 | $key_array = array_fill( 0, count($value_arr), $key_array ); |
22 | - //\common\components\CustomVarDamp::dumpAndDie($key_array); | 26 | + // \common\components\CustomVarDamp::dumpAndDie($key_array); |
23 | $result = array_map( | 27 | $result = array_map( |
24 | function ($value, $key_array) { | 28 | function ($value, $key_array) { |
25 | $res = $value; | 29 | $res = $value; |
@@ -40,4 +44,14 @@ class CustomConverter extends Converter { | @@ -40,4 +44,14 @@ class CustomConverter extends Converter { | ||
40 | return $result; | 44 | return $result; |
41 | } | 45 | } |
42 | 46 | ||
47 | + public function addColumn ($value_arr, $add_key, $add_value) | ||
48 | + { | ||
49 | + $i = 0; | ||
50 | + while ($i < count($value_arr)) { | ||
51 | + $value_arr[$i][$add_key] = $add_value; | ||
52 | + $i++; | ||
53 | + } | ||
54 | + | ||
55 | + return $value_arr; | ||
56 | + } | ||
43 | } | 57 | } |
44 | \ No newline at end of file | 58 | \ No newline at end of file |
backend/components/parsers/CustomCsvParser.php
@@ -11,24 +11,32 @@ namespace backend\components\parsers; | @@ -11,24 +11,32 @@ namespace backend\components\parsers; | ||
11 | 11 | ||
12 | class CustomCsvParser extends \yii\multiparser\CsvParser { | 12 | class CustomCsvParser extends \yii\multiparser\CsvParser { |
13 | 13 | ||
14 | - public $last_line = 10; | 14 | + public $last_line = 20; |
15 | //public $hasHeaderRow = true; | 15 | //public $hasHeaderRow = true; |
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 | - | 19 | + if (!count($this->converter_conf)) { |
21 | if ($this->hasHeaderRow) { | 20 | if ($this->hasHeaderRow) { |
22 | // если у файла есть заголовок, то в результате имеем ассоциативный массив | 21 | // если у файла есть заголовок, то в результате имеем ассоциативный массив |
23 | $this->converter_conf['hasKey'] = 1; | 22 | $this->converter_conf['hasKey'] = 1; |
24 | } | 23 | } |
25 | 24 | ||
26 | - $this->converter = \Yii::createObject($this->converter_conf); | ||
27 | - | ||
28 | } | 25 | } |
29 | 26 | ||
30 | - | ||
31 | } | 27 | } |
32 | 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 | + } | ||
33 | 41 | ||
34 | } | 42 | } |
35 | \ No newline at end of file | 43 | \ No newline at end of file |
backend/controllers/ParserController.php
@@ -10,16 +10,19 @@ use yii\web\UploadedFile; | @@ -10,16 +10,19 @@ use yii\web\UploadedFile; | ||
10 | use yii\data\ArrayDataProvider; | 10 | use yii\data\ArrayDataProvider; |
11 | use yii\multiparser\DynamicFormHelper; | 11 | use yii\multiparser\DynamicFormHelper; |
12 | use backend\components\parsers\CustomParserConfigurator; | 12 | use backend\components\parsers\CustomParserConfigurator; |
13 | +use backend\models\Details; | ||
14 | +use backend\models\ImporterFiles; | ||
15 | +use yii\base\ErrorException; | ||
13 | 16 | ||
14 | use common\components\CustomVarDamp; | 17 | use common\components\CustomVarDamp; |
15 | 18 | ||
16 | /** | 19 | /** |
17 | * Parser controller | 20 | * Parser controller |
18 | */ | 21 | */ |
19 | - | ||
20 | class ParserController extends BaseController | 22 | class ParserController extends BaseController |
21 | { | 23 | { |
22 | public $layout = "/column"; | 24 | public $layout = "/column"; |
25 | + | ||
23 | /** | 26 | /** |
24 | * @inheritdoc | 27 | * @inheritdoc |
25 | */ | 28 | */ |
@@ -30,7 +33,7 @@ class ParserController extends BaseController | @@ -30,7 +33,7 @@ class ParserController extends BaseController | ||
30 | 'class' => AccessControl::className(), | 33 | 'class' => AccessControl::className(), |
31 | 'rules' => [ | 34 | 'rules' => [ |
32 | [ | 35 | [ |
33 | - 'actions' => ['index','results','write'], | 36 | + 'actions' => ['index', 'results', 'write'], |
34 | 'allow' => true, | 37 | 'allow' => true, |
35 | 'roles' => ['@'], | 38 | 'roles' => ['@'], |
36 | ], | 39 | ], |
@@ -58,7 +61,6 @@ class ParserController extends BaseController | @@ -58,7 +61,6 @@ class ParserController extends BaseController | ||
58 | } | 61 | } |
59 | 62 | ||
60 | 63 | ||
61 | - | ||
62 | public function actionIndex() | 64 | public function actionIndex() |
63 | { | 65 | { |
64 | $model = new UploadFileParsingForm(); | 66 | $model = new UploadFileParsingForm(); |
@@ -66,26 +68,31 @@ class ParserController extends BaseController | @@ -66,26 +68,31 @@ class ParserController extends BaseController | ||
66 | return $this->render('index', ['model' => $model]); | 68 | return $this->render('index', ['model' => $model]); |
67 | } | 69 | } |
68 | 70 | ||
69 | - public function actionResults(){ | 71 | + public function actionResults() |
72 | + { | ||
70 | 73 | ||
71 | $model = new UploadFileParsingForm(); | 74 | $model = new UploadFileParsingForm(); |
72 | $data = []; | 75 | $data = []; |
73 | if ($model->load(Yii::$app->request->post())) { | 76 | if ($model->load(Yii::$app->request->post())) { |
74 | $model->file = UploadedFile::getInstance($model, 'file'); | 77 | $model->file = UploadedFile::getInstance($model, 'file'); |
75 | - | 78 | + // первый проход - валидируем, сохраняем файл, ложим в кеш отпарсенные данные и параметры модели (потом при записи в базу данных они пригодятся) |
76 | if ($model->validate()) { | 79 | if ($model->validate()) { |
77 | $filePath = Yii::getAlias('@webroot') . '/uploads/' . $model->file->baseName . '.' . $model->file->extension; | 80 | $filePath = Yii::getAlias('@webroot') . '/uploads/' . $model->file->baseName . '.' . $model->file->extension; |
78 | 81 | ||
79 | - $model->file->saveAs( $filePath ); | 82 | + $model->file->saveAs($filePath); |
83 | + //запускаем парсинг | ||
80 | $data = $model->readFile($filePath); | 84 | $data = $model->readFile($filePath); |
85 | + // сохраняем в кеш отпарсенные даные | ||
86 | + Yii::$app->getCache()->set('parser_data', json_encode($data)); | ||
87 | + // сохраняем в кеш модель - в ней настройки для дальнейшей обработки данных | ||
88 | + Yii::$app->getCache()->set('parser_configuration', serialize($model)); | ||
81 | 89 | ||
82 | - Yii::$app->getCache()->set( 'parser_data', json_encode($data) ); | ||
83 | 90 | ||
84 | } | 91 | } |
92 | + // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные | ||
93 | + } else if (Yii::$app->getCache()->get('parser_data')) { | ||
85 | 94 | ||
86 | - } else if( Yii::$app->getCache()->get( 'parser_data' )) { | ||
87 | - | ||
88 | - $data = json_decode( Yii::$app->getCache()->get( 'parser_data' ),true ); | 95 | + $data = json_decode(Yii::$app->getCache()->get('parser_data'), true); |
89 | 96 | ||
90 | } | 97 | } |
91 | 98 | ||
@@ -96,40 +103,99 @@ class ParserController extends BaseController | @@ -96,40 +103,99 @@ class ParserController extends BaseController | ||
96 | ], | 103 | ], |
97 | ]); | 104 | ]); |
98 | 105 | ||
99 | - //CustomVarDamp::dumpAndDie($data); | ||
100 | - $header_model = DynamicFormHelper::CreateDynamicModel( count( $data[0] ) ); | 106 | + //формируем заголовок для пользователя, где он сможет выбрать соответсвие полей (выпадающий список) |
107 | + $header_model = DynamicFormHelper::CreateDynamicModel(count($data[0])); | ||
101 | 108 | ||
102 | - // CustomVarDamp::dumpAndDie(Yii::$app->multiparser->getConfiguration('csv','basic_column')); | ||
103 | return $this->render('results', | 109 | return $this->render('results', |
104 | ['model' => $data, | 110 | ['model' => $data, |
105 | 'header_model' => $header_model, | 111 | 'header_model' => $header_model, |
106 | - 'basic_column' => Yii::$app->multiparser->getConfiguration('csv','basic_column'), | 112 | + // список колонок для выбора |
113 | + 'basic_column' => Yii::$app->multiparser->getConfiguration('csv', 'basic_column'), | ||
107 | 'dataProvider' => $provider]); | 114 | 'dataProvider' => $provider]); |
108 | } | 115 | } |
109 | 116 | ||
110 | -public function actionWrite() | ||
111 | -{ | ||
112 | - //CustomVarDamp::dumpAndDie(Yii::$app->request->post()); | 117 | + public function actionWrite() |
118 | + { | ||
113 | 119 | ||
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 | - } | 120 | + //получим колонки которые выбрал пользователь |
121 | + $arr_attributes = Yii::$app->request->post()['DynamicModel']; | ||
122 | + //соберем модель по полученным данным | ||
123 | + $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); | ||
124 | + //добавим правила валидации (колонки должны быть те что указаны в конфиге) | ||
125 | + foreach ($arr_attributes as $key => $value) { | ||
126 | + $model->addRule($key, 'in', ['range' => array_keys(Yii::$app->multiparser->getConfiguration('csv', 'basic_column'))]); | ||
127 | + } | ||
119 | 128 | ||
129 | + // провалидируем выбранные колонки | ||
130 | + if ($model->validate()) { | ||
120 | 131 | ||
121 | - //CustomVarDamp::dumpAndDie($model); | ||
122 | - if ($model->validate()) { | ||
123 | - $arr = $model->toArray(); | ||
124 | - $data = json_decode( Yii::$app->getCache()->get( 'parser_data' ),true ); | 132 | + // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы |
133 | + $arr = $model->toArray(); | ||
125 | 134 | ||
126 | - $data = \Yii::$app->multiparser->convertToAssocArray( $data, $arr, 'attr_' ); | ||
127 | - $data[1]['BOX'] = \Yii::$app->multiparser->convertToFloat( $data[1]['BOX'] ); | ||
128 | - CustomVarDamp::dumpAndDie($data); | ||
129 | - } | 135 | + // получим данные из кеша |
136 | + if (Yii::$app->getCache()->get('parser_data') && Yii::$app->getCache()->get('parser_configuration')) { | ||
137 | + $data = json_decode(Yii::$app->getCache()->get('parser_data'), true); | ||
138 | + $configuration = unserialize(Yii::$app->getCache()->get('parser_configuration')); | ||
139 | + } else { | ||
140 | + CustomVarDamp::dumpAndDie('Ошибка кеша'); | ||
141 | + } | ||
130 | 142 | ||
143 | + // соотнесем отпарсенные данные с соответсивем полученным от пользователя | ||
144 | + // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию | ||
145 | + $data = \Yii::$app->multiparser->convertToAssocArray($data, $arr, 'attr_'); | ||
146 | + | ||
147 | + | ||
148 | + // запишем дату старта в таблицу файлов поставщика (ImportersFiles) | ||
149 | + $files_model = new ImporterFiles(); | ||
150 | + // id поставщика получим из конфигурации | ||
151 | + $files_model->load(['ImporterFiles' => $configuration->toArray()]); | ||
152 | + if ($files_model->validate()) { | ||
153 | + try { | ||
154 | + $files_model->save(); | ||
155 | + } catch (ErrorException $e) { | ||
156 | + CustomVarDamp::dump($e->getMessage()); | ||
157 | + } | ||
158 | + | ||
159 | + | ||
160 | + // запишем полученные данные в таблицу товаров (Details) | ||
161 | + $details_model = new Details('web'); | ||
162 | + // проверим все ли обязательные колонки были указаны пользователем | ||
163 | + $details_model->load(['Details' => $data[0]]); | ||
164 | + if ($details_model->validate()) { | ||
165 | + // проставим импортера | ||
166 | + $data = $details_model->prepareData($data, $configuration); | ||
167 | + | ||
168 | + try { | ||
169 | + // попытаемся вставить данные в БД с апдейтом по ключам | ||
170 | + $details_model->save($data); | ||
171 | + | ||
172 | + // а также зафиксируем дату конца загрузки | ||
173 | + $files_model->time_end = mktime(); // ошибка!!!!!!!!!!!!!!!! | ||
174 | + $files_model->save(); | ||
175 | + | ||
176 | + // все прошло успешно - очищаем кеш | ||
177 | + Yii::$app->getCache()->delete('parser_data'); | ||
178 | + Yii::$app->getCache()->delete('parser_configuration'); | ||
179 | + | ||
180 | + CustomVarDamp::dumpAndDie('!!!'); | ||
181 | + } catch (ErrorException $e) { | ||
182 | + CustomVarDamp::dump($e->getMessage()); | ||
183 | + } | ||
184 | + } | ||
185 | + if ($details_model->hasErrors()) { | ||
186 | + $errors_arr = $details_model->getErrors(); | ||
187 | + foreach ($errors_arr as $error) { | ||
188 | + CustomVarDamp::dump(array_values($error)); | ||
189 | + } | ||
190 | + | ||
191 | + } | ||
131 | 192 | ||
132 | 193 | ||
133 | -} | 194 | + } |
195 | + | ||
196 | + | ||
197 | + } | ||
198 | + | ||
199 | + } | ||
134 | 200 | ||
135 | } | 201 | } |
backend/models/Details.php
@@ -9,11 +9,127 @@ | @@ -9,11 +9,127 @@ | ||
9 | namespace backend\models; | 9 | namespace backend\models; |
10 | 10 | ||
11 | use yii\base\Model; | 11 | use yii\base\Model; |
12 | +use Yii; | ||
12 | 13 | ||
13 | class Details extends Model{ | 14 | class Details extends Model{ |
15 | + const KEY_COLUMN = ['IMPORT_ID','BRAND','ARTICLE']; | ||
16 | + const BATCH = 500; | ||
14 | 17 | ||
15 | - public function save ($arr_value) | 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) | ||
16 | { | 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 | + | ||
89 | + $res = Yii::$app->db->createCommand($query)->execute(); | ||
90 | + | ||
91 | + } | ||
17 | 92 | ||
18 | } | 93 | } |
19 | -} | ||
20 | \ No newline at end of file | 94 | \ No newline at end of file |
95 | +} | ||
96 | + | ||
97 | +// | ||
98 | + | ||
99 | +//$q = " INSERT INTO {$table_name} ({$keys_string}) VALUES ("; | ||
100 | + | ||
101 | +//$q .= " on duplicate key update `FULL_ARTICLE` = values (`FULL_ARTICLE`), | ||
102 | +// `PRICE` = values (`PRICE`), | ||
103 | +// `DESCR` = values(`DESCR`), | ||
104 | +// `BOX` = values(`BOX`), | ||
105 | +// `ADD_BOX` = values(`ADD_BOX`), | ||
106 | +// `GROUP` = values(`GROUP`);"; | ||
107 | + | ||
108 | +// INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) | ||
109 | +// ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b); | ||
110 | + | ||
111 | + | ||
112 | + | ||
113 | +//INSERT INTO `books` (`UserId`, `BookId`, `Count`) VALUES (13, 1001, 3) | ||
114 | +//ON DUPLICATE KEY UPDATE `Count` = `Count` + VALUES(`Count`); | ||
115 | + | ||
116 | +//$values_string = ''; | ||
117 | +//$keys_arr = array_keys( $data[0] ); | ||
118 | +//$keys_string = implode( ',', $keys_arr); | ||
119 | +//$table_name = self::tableName(); | ||
120 | +//$current_batch = 0; | ||
121 | +//for ($i = $current_batch; $i < $this::BATCH AND $i < count($data); $i++) { | ||
122 | +// $values_string .= '(' . implode( ',', $data[$i]) . '),'; | ||
123 | +//} | ||
124 | +// for ($current_batch = $this::BATCH; $current_batch<count($data); $current_batch + $this::BATCH ) | ||
125 | +//// удалим последнюю запятую | ||
126 | +//$values_string = substr($values_string, 0, strlen($values_string) - 1) . ' '; | ||
127 | +////\common\components\CustomVarDamp::dumpAndDie($values_string); | ||
128 | +//// $query = "INSERT INTO {$table_name}({$keys_string}) VALUES {$values_string}"; | ||
129 | +//// on duplicate key update `PRICE` = values (`PRICE`),`DESCR` = values(`DESCR`),`BOX` = values(`BOX`)"; | ||
130 | +//$query_insert = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $data)->sql; | ||
131 | +//$query = "{$query_insert} on duplicate key update `PRICE` = values (`PRICE`),`DESCR` = values(`DESCR`),`BOX` = values(`BOX`)"; | ||
132 | +//$res = Yii::$app->db->createCommand($query)->execute(); | ||
133 | + | ||
134 | + | ||
135 | + | ||
136 | +// Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $data)->sql execute(); | ||
21 | \ No newline at end of file | 137 | \ No newline at end of file |
1 | +<?php | ||
2 | + | ||
3 | +namespace backend\models; | ||
4 | + | ||
5 | +use Yii; | ||
6 | + | ||
7 | +/** | ||
8 | + * This is the model class for table "{{%importer_files}}". | ||
9 | + * | ||
10 | + * @property integer $id | ||
11 | + * @property string $importer_id | ||
12 | + * @property string $upload_time | ||
13 | + * @property string $time_start | ||
14 | + * @property string $time_end | ||
15 | + */ | ||
16 | +class ImporterFiles extends \yii\db\ActiveRecord | ||
17 | +{ | ||
18 | + /** | ||
19 | + * @inheritdoc | ||
20 | + */ | ||
21 | + public static function tableName() | ||
22 | + { | ||
23 | + return '{{%importer_files}}'; | ||
24 | + } | ||
25 | + | ||
26 | + /** | ||
27 | + * @inheritdoc | ||
28 | + */ | ||
29 | + public function rules() | ||
30 | + { | ||
31 | + return [ | ||
32 | + [['importer_id'], 'required'], | ||
33 | + [['importer_id'], 'integer'], | ||
34 | + [['upload_time', 'time_start', 'time_end'], 'safe'] | ||
35 | + ]; | ||
36 | + } | ||
37 | + | ||
38 | + /** | ||
39 | + * @inheritdoc | ||
40 | + */ | ||
41 | + public function attributeLabels() | ||
42 | + { | ||
43 | + return [ | ||
44 | + 'id' => Yii::t('app', 'ID'), | ||
45 | + 'importer_id' => Yii::t('app', 'Importer ID'), | ||
46 | + 'upload_time' => Yii::t('app', 'Upload Time'), | ||
47 | + 'time_start' => Yii::t('app', 'Time Start'), | ||
48 | + 'time_end' => Yii::t('app', 'Time End'), | ||
49 | + ]; | ||
50 | + } | ||
51 | +} |
backend/models/UploadFileParsingForm.php
@@ -15,7 +15,7 @@ class UploadFileParsingForm extends Model | @@ -15,7 +15,7 @@ class UploadFileParsingForm extends Model | ||
15 | * @var UploadedFile file attribute | 15 | * @var UploadedFile file attribute |
16 | */ | 16 | */ |
17 | public $file; | 17 | public $file; |
18 | - public $importer; | 18 | + public $importer_id; |
19 | public $action; | 19 | public $action; |
20 | public $delimiter; | 20 | public $delimiter; |
21 | public $delete_price; | 21 | public $delete_price; |
@@ -27,12 +27,12 @@ class UploadFileParsingForm extends Model | @@ -27,12 +27,12 @@ class UploadFileParsingForm extends Model | ||
27 | public function rules() | 27 | public function rules() |
28 | { | 28 | { |
29 | return [ | 29 | return [ |
30 | - ['importer', 'required', 'message' => 'Не указан поставщик!' ], | 30 | + ['importer_id', 'required', 'message' => 'Не указан поставщик!' ], |
31 | ['file', 'required', 'message' => 'Не выбран файл!' ], | 31 | ['file', 'required', 'message' => 'Не выбран файл!' ], |
32 | //@todo - not working this file validator!!! - fixed | 32 | //@todo - not working this file validator!!! - fixed |
33 | [['file'], 'file'],// 'extensions' => ['csv', 'xml'] ], | 33 | [['file'], 'file'],// 'extensions' => ['csv', 'xml'] ], |
34 | // 'wrongMimeType' => 'Указан неподдерживаемый тип файла. Можно выбирать csv, xml файлы.' ], | 34 | // 'wrongMimeType' => 'Указан неподдерживаемый тип файла. Можно выбирать csv, xml файлы.' ], |
35 | - ['importer', 'integer','max' => 999999, 'min' => 0 ], | 35 | + ['importer_id', 'integer','max' => 999999, 'min' => 0 ], |
36 | [['action','delete_prefix', 'delete_price'], 'boolean'], | 36 | [['action','delete_prefix', 'delete_price'], 'boolean'], |
37 | ['delimiter', 'string', 'max' => 1], | 37 | ['delimiter', 'string', 'max' => 1], |
38 | ['delimiter', 'default', 'value' => ';'] | 38 | ['delimiter', 'default', 'value' => ';'] |
@@ -44,7 +44,7 @@ class UploadFileParsingForm extends Model | @@ -44,7 +44,7 @@ class UploadFileParsingForm extends Model | ||
44 | { | 44 | { |
45 | return [ | 45 | return [ |
46 | 'file' => Yii::t('app', 'Источник'), | 46 | 'file' => Yii::t('app', 'Источник'), |
47 | - 'importer' => Yii::t('app', 'Поставщик'), | 47 | + 'importer_id' => Yii::t('app', 'Поставщик'), |
48 | 'delimiter' => Yii::t('app', 'Разделитель'), | 48 | 'delimiter' => Yii::t('app', 'Разделитель'), |
49 | ]; | 49 | ]; |
50 | } | 50 | } |
@@ -55,6 +55,8 @@ class UploadFileParsingForm extends Model | @@ -55,6 +55,8 @@ class UploadFileParsingForm extends Model | ||
55 | if( !is_array($data) ){ | 55 | if( !is_array($data) ){ |
56 | $data = ['No results']; | 56 | $data = ['No results']; |
57 | } | 57 | } |
58 | + | ||
58 | return $data; | 59 | return $data; |
59 | } | 60 | } |
61 | + | ||
60 | } | 62 | } |
61 | \ No newline at end of file | 63 | \ No newline at end of file |
backend/views/parser/index.php
@@ -15,7 +15,7 @@ use yii\helpers\ArrayHelper; | @@ -15,7 +15,7 @@ use yii\helpers\ArrayHelper; | ||
15 | <h3>Загрузка прайсов поставщиков</h3> | 15 | <h3>Загрузка прайсов поставщиков</h3> |
16 | 16 | ||
17 | 17 | ||
18 | - <?= $form->field($model, 'importer')->dropDownList(ArrayHelper::map( Importer::find()->all(), 'id','name' )); ?> | 18 | + <?= $form->field($model, 'importer_id')->dropDownList(ArrayHelper::map( Importer::find()->all(), 'id','name' )); ?> |
19 | <?= $form->field($model, 'delete_price')->checkbox(['label' => 'Загрузить с удалением старого прайса']) ?> | 19 | <?= $form->field($model, 'delete_price')->checkbox(['label' => 'Загрузить с удалением старого прайса']) ?> |
20 | <?= $form->field($model, 'file')->fileInput()->label(false) ?> | 20 | <?= $form->field($model, 'file')->fileInput()->label(false) ?> |
21 | <?= $form->field($model, 'action')->radioList([1 => 'Стандартная обработка', 0 => 'С разделителем'])->label(false) ?> | 21 | <?= $form->field($model, 'action')->radioList([1 => 'Стандартная обработка', 0 => 'С разделителем'])->label(false) ?> |
console/migrations/m150915_125129_addDetails.php
@@ -7,45 +7,27 @@ class m150915_125129_addDetails extends Migration | @@ -7,45 +7,27 @@ class m150915_125129_addDetails extends Migration | ||
7 | { | 7 | { |
8 | public function up() | 8 | public function up() |
9 | { | 9 | { |
10 | - $tableOptions = null; | ||
11 | - if ($this->db->driverName === 'mysql') { | ||
12 | - $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; | ||
13 | - } | ||
14 | - | ||
15 | - $this->createTable('{{%details}}', [ | ||
16 | - 'ID' => 'int(10) UNSIGNED NOT NULL', | ||
17 | - 'IMPORT_ID' => 'int(6) unsigned NOT NULL', | ||
18 | - 'BRAND' => 'varchar(100) NOT NULL', | ||
19 | - 'ARTICLE' => 'varchar(100) NOT NULL', | ||
20 | - 'FULL_ARTICLE' => 'varchar(150) NOT NULL', | ||
21 | - 'PRICE' => 'float(15,2) unsigned NOT NULL', | ||
22 | - 'DESCR' => 'varchar(200) NOT NULL', | ||
23 | - 'BOX' => 'int(6) unsigned NOT NULL', | ||
24 | - 'ADD_BOX' => 'int(6) unsigned NOT NULL DEFAULT 0', | ||
25 | - 'GROUP' => 'varchar(200) NOT NULL', | ||
26 | - 'timestamp' => 'timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP',], $tableOptions); | ||
27 | - | ||
28 | - //$this->dropPrimaryKey('ID','{{%details}}'); | ||
29 | - $this->createIndex('ID_delete', '{{%details}}', 'ID', true); | ||
30 | - $this->execute('ALTER TABLE details | ||
31 | - CHANGE COLUMN ID ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT'); | ||
32 | - $this->addPrimaryKey('importer_id', '{{%details}}', 'import_id, brand, ARTICLE'); | ||
33 | - $this->createIndex('timestamp', '{{%details}}', 'timestamp', false); | ||
34 | - $this->createIndex('ARTICLE', '{{%details}}', 'ARTICLE', 'BRAND', 'ADD_BOX', false); | ||
35 | - $this->createIndex('IMPORT_ID', '{{%details}}', 'ARTICLE', false); | ||
36 | - $this->createIndex('IMPORT_ID_2', '{{%details}}', 'IMPORT_ID', 'timestamp', false); | ||
37 | - | ||
38 | - | ||
39 | - | ||
40 | - | ||
41 | -// PRIMARY KEY ('ARTICLE','BRAND','IMPORT_ID'), | ||
42 | -// UNIQUE KEY 'ID_delete' ('ID'), | ||
43 | -// KEY 'timestamp' ('timestamp'), | ||
44 | -// KEY 'ARTICLE' ('ARTICLE','BRAND','BOX'), | ||
45 | -// KEY 'BRAND' ('BRAND','ARTICLE'), | ||
46 | -// KEY 'ARTICLE_2' ('ARTICLE','BRAND','ADD_BOX'), | ||
47 | -// KEY 'IMPORT_ID' ('IMPORT_ID','ARTICLE'), | ||
48 | -// KEY 'IMPORT_ID_2' ('IMPORT_ID','timestamp | 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'); | ||
49 | 31 | ||
50 | } | 32 | } |
51 | 33 | ||
@@ -55,14 +37,4 @@ class m150915_125129_addDetails extends Migration | @@ -55,14 +37,4 @@ class m150915_125129_addDetails extends Migration | ||
55 | 37 | ||
56 | } | 38 | } |
57 | 39 | ||
58 | - /* | ||
59 | - // Use safeUp/safeDown to run migration code within a transaction | ||
60 | - public function safeUp() | ||
61 | - { | ||
62 | - } | ||
63 | - | ||
64 | - public function safeDown() | ||
65 | - { | ||
66 | - } | ||
67 | - */ | ||
68 | } | 40 | } |
vendor/yiisoft/multiparser/Converter.php
@@ -15,9 +15,9 @@ class Converter extends Behavior | @@ -15,9 +15,9 @@ class Converter extends Behavior | ||
15 | 15 | ||
16 | const METHOD_PREFIX = 'convertTo'; | 16 | const METHOD_PREFIX = 'convertTo'; |
17 | 17 | ||
18 | - public $configuration = []; | 18 | + //public $configuration = []; |
19 | 19 | ||
20 | - protected static function convertToFloat($value) | 20 | + public static function convertToFloat($value) |
21 | { | 21 | { |
22 | echo 1; | 22 | echo 1; |
23 | if ($value == '') { | 23 | if ($value == '') { |
@@ -34,7 +34,7 @@ class Converter extends Behavior | @@ -34,7 +34,7 @@ class Converter extends Behavior | ||
34 | return $value; | 34 | return $value; |
35 | } | 35 | } |
36 | 36 | ||
37 | - protected static function convertToInteger($value) | 37 | + public static function convertToInteger($value) |
38 | { | 38 | { |
39 | if ($value == '') { | 39 | if ($value == '') { |
40 | $value = 0; | 40 | $value = 0; |
@@ -49,7 +49,7 @@ class Converter extends Behavior | @@ -49,7 +49,7 @@ class Converter extends Behavior | ||
49 | return $value; | 49 | return $value; |
50 | } | 50 | } |
51 | 51 | ||
52 | - protected static function convertToString($value) | 52 | + public static function convertToString($value) |
53 | { | 53 | { |
54 | 54 | ||
55 | 55 | ||
@@ -93,16 +93,17 @@ class Converter extends Behavior | @@ -93,16 +93,17 @@ class Converter extends Behavior | ||
93 | 93 | ||
94 | 94 | ||
95 | /** | 95 | /** |
96 | - * @param $arr - массив | 96 | + * @param $arr - массив для конвертирования |
97 | + * @param $configuration - массив конфигурация конвертирования | ||
97 | * @return mixed | 98 | * @return mixed |
98 | * конвертирует массив по полученным настройкам, вызывая последовательно функции конвертации (указанные в конфигурации) | 99 | * конвертирует массив по полученным настройкам, вызывая последовательно функции конвертации (указанные в конфигурации) |
99 | */ | 100 | */ |
100 | - public function convertByConfiguration( $arr ) | 101 | + public static function convertByConfiguration( $arr, $configuration ) |
101 | { | 102 | { |
102 | $result = $arr; | 103 | $result = $arr; |
103 | - | ||
104 | - $hasKey = isset( $this->configuration['hasKey'] ); | ||
105 | - foreach ( $this->configuration as $key => $value ) { | 104 | + //\common\components\CustomVarDamp::dumpAndDie($configuration); |
105 | + $hasKey = isset( $configuration['hasKey'] ); | ||
106 | + foreach ( $configuration['configuration'] as $key => $value ) { | ||
106 | 107 | ||
107 | if ( $hasKey ){ | 108 | if ( $hasKey ){ |
108 | // у нас ассоциативный массив, и мы можем конвертировать каждое значение в отдельности | 109 | // у нас ассоциативный массив, и мы можем конвертировать каждое значение в отдельности |
vendor/yiisoft/multiparser/CsvParser.php
@@ -78,7 +78,7 @@ class CsvParser implements ParserInterface | @@ -78,7 +78,7 @@ class CsvParser implements ParserInterface | ||
78 | // если у файла есть заголовок, то в результате имеем ассоциативный массив | 78 | // если у файла есть заголовок, то в результате имеем ассоциативный массив |
79 | $this->converter_conf['hasKey'] = 1; | 79 | $this->converter_conf['hasKey'] = 1; |
80 | } | 80 | } |
81 | - $this->converter->configuration = $this->converter_conf; | 81 | + //$this->converter->configuration = $this->converter_conf; |
82 | 82 | ||
83 | } | 83 | } |
84 | } | 84 | } |
@@ -198,7 +198,7 @@ class CsvParser implements ParserInterface | @@ -198,7 +198,7 @@ class CsvParser implements ParserInterface | ||
198 | 198 | ||
199 | if (!is_null($converter)) { | 199 | if (!is_null($converter)) { |
200 | 200 | ||
201 | - $result = $converter->convertByConfiguration( $arr ); | 201 | + $result = $converter->convertByConfiguration( $arr, $this->converter_conf ); |
202 | 202 | ||
203 | } | 203 | } |
204 | 204 |