Commit 209dad04425c8ac8b66042f456a208f0696ccfea
1 parent
9195565b
add validator for requiremetts coloumn in parser forms
Showing
13 changed files
with
137 additions
and
216 deletions
Show diff stats
backend/controllers/CrossingUploadController.php
@@ -116,13 +116,16 @@ class CrossingUploadController extends BaseController | @@ -116,13 +116,16 @@ class CrossingUploadController extends BaseController | ||
116 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; | 116 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; |
117 | //соберем модель по полученным данным | 117 | //соберем модель по полученным данным |
118 | $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); | 118 | $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); |
119 | + $crosses_model = new DetailsCrosses(); | ||
119 | //добавим правила валидации (колонки должны быть те что в модели) | 120 | //добавим правила валидации (колонки должны быть те что в модели) |
120 | foreach ($arr_attributes as $key => $value) { | 121 | foreach ($arr_attributes as $key => $value) { |
121 | $model->addRule($key, 'in', [ 'range' => array_keys( $this->getBasicColumns() ) ]); | 122 | $model->addRule($key, 'in', [ 'range' => array_keys( $this->getBasicColumns() ) ]); |
122 | } | 123 | } |
123 | - | 124 | + // установим режим проверки обязательных полей |
125 | + $crosses_model->setScenario('form_upload_validation'); | ||
126 | + $model_validator = new ModelArrayValidator( $crosses_model ); | ||
124 | // провалидируем выбранные колонки | 127 | // провалидируем выбранные колонки |
125 | - if ( $model->validate() ) { | 128 | + if ( $model->validate() && $model_validator->validateRow( array_flip( $arr_attributes ) ) ) { |
126 | 129 | ||
127 | // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы | 130 | // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы |
128 | $arr = $model->toArray(); | 131 | $arr = $model->toArray(); |
@@ -138,8 +141,7 @@ class CrossingUploadController extends BaseController | @@ -138,8 +141,7 @@ class CrossingUploadController extends BaseController | ||
138 | $data = $this->convertDataByConfiguration( $data, $configuration ); | 141 | $data = $this->convertDataByConfiguration( $data, $configuration ); |
139 | 142 | ||
140 | // валидируем отпарсенные данные моделью в которую будем записывать | 143 | // валидируем отпарсенные данные моделью в которую будем записывать |
141 | - $crosses_model = new DetailsCrosses(); | ||
142 | - $model_validator = new ModelArrayValidator( $crosses_model ); | 144 | + $crosses_model->setScenario('default'); |
143 | $data = $model_validator->validate( $data ); | 145 | $data = $model_validator->validate( $data ); |
144 | $msg = $model_validator->getMassage(); | 146 | $msg = $model_validator->getMassage(); |
145 | $type_msg = $model_validator->hasError() ? 'warning' : 'success'; | 147 | $type_msg = $model_validator->hasError() ? 'warning' : 'success'; |
@@ -162,8 +164,8 @@ class CrossingUploadController extends BaseController | @@ -162,8 +164,8 @@ class CrossingUploadController extends BaseController | ||
162 | 164 | ||
163 | } else { | 165 | } else { |
164 | // не прошла валидация формы загрузки файлов | 166 | // не прошла валидация формы загрузки файлов |
165 | - $errors_str = ''; | ||
166 | - foreach ($model->getErrors() as $error) { | 167 | + $errors_str = "Ошибка валидации формы загрузки файлов. "; |
168 | + foreach ($crosses_model->getErrors() as $error) { | ||
167 | $errors_str .= implode(array_values($error)); | 169 | $errors_str .= implode(array_values($error)); |
168 | } | 170 | } |
169 | throw new \ErrorException($errors_str); | 171 | throw new \ErrorException($errors_str); |
backend/controllers/ParserController.php
1 | <?php | 1 | <?php |
2 | namespace backend\controllers; | 2 | namespace backend\controllers; |
3 | 3 | ||
4 | +use backend\models\Details; | ||
4 | use common\components\archives\ArchiveCreator; | 5 | use common\components\archives\ArchiveCreator; |
5 | use common\components\mail\ImapMailReader; | 6 | use common\components\mail\ImapMailReader; |
6 | use common\components\mail\MailAttachmentsSaver; | 7 | use common\components\mail\MailAttachmentsSaver; |
8 | +use common\components\ModelArrayValidator; | ||
7 | use common\components\parsers\MailParser; | 9 | use common\components\parsers\MailParser; |
8 | use Yii; | 10 | use Yii; |
9 | use yii\data\ActiveDataProvider; | 11 | use yii\data\ActiveDataProvider; |
@@ -72,14 +74,13 @@ class ParserController extends BaseController | @@ -72,14 +74,13 @@ class ParserController extends BaseController | ||
72 | 74 | ||
73 | public function actionResults($mode = 0) | 75 | public function actionResults($mode = 0) |
74 | { | 76 | { |
77 | + set_time_limit(600); | ||
75 | $model = new UploadFileParsingForm( ['mode' => $mode] ); | 78 | $model = new UploadFileParsingForm( ['mode' => $mode] ); |
76 | $data = []; | 79 | $data = []; |
77 | if ( $model->load(Yii::$app->request->post()) ) { | 80 | if ( $model->load(Yii::$app->request->post()) ) { |
78 | - $model->file = UploadedFile::getInstance($model, 'file'); | ||
79 | - // первый проход - валидируем, | ||
80 | - // сохраняем файл, | 81 | + $model->file = UploadedFile::getInstance( $model, 'file' ); |
82 | + // первый проход - валидируем, сохраняем файл, | ||
81 | // ложим в кеш (для ручной загрузки) отпарсенные данные и параметры модели | 83 | // ложим в кеш (для ручной загрузки) отпарсенные данные и параметры модели |
82 | - // (потом при записи в базу данных они пригодятся) | ||
83 | if ( $model->validate() ) { | 84 | if ( $model->validate() ) { |
84 | // сохраним файл и создадим модель - ImportersFiles | 85 | // сохраним файл и создадим модель - ImportersFiles |
85 | $files_model = $this->saveParserFile($model); | 86 | $files_model = $this->saveParserFile($model); |
@@ -95,12 +96,11 @@ class ParserController extends BaseController | @@ -95,12 +96,11 @@ class ParserController extends BaseController | ||
95 | 96 | ||
96 | } else { | 97 | } else { |
97 | // не прошла валидация форма загрузки файлов | 98 | // не прошла валидация форма загрузки файлов |
98 | -// $errors_str = ''; | ||
99 | -// foreach ($model->getErrors() as $error) { | ||
100 | -// $errors_str .= implode( array_values($error) ); | ||
101 | -// } | ||
102 | -// throw new ErrorException( $errors_str ); | ||
103 | - $model->throwStringErrorException(); | 99 | + $errors_str = ''; |
100 | + foreach ($model->getErrors() as $error) { | ||
101 | + $errors_str .= implode( array_values($error) ); | ||
102 | + } | ||
103 | + throw new ErrorException( $errors_str ); | ||
104 | } | 104 | } |
105 | // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные | 105 | // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные |
106 | } else if ( Yii::$app->getCache()->get('parser_data') ) { | 106 | } else if ( Yii::$app->getCache()->get('parser_data') ) { |
@@ -135,13 +135,17 @@ class ParserController extends BaseController | @@ -135,13 +135,17 @@ class ParserController extends BaseController | ||
135 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; | 135 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; |
136 | //соберем модель по полученным данным | 136 | //соберем модель по полученным данным |
137 | $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); | 137 | $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); |
138 | + $details_model = new Details(); | ||
138 | //добавим правила валидации (колонки должны быть те что указаны в конфиге) | 139 | //добавим правила валидации (колонки должны быть те что указаны в конфиге) |
139 | foreach ($arr_attributes as $key => $value) { | 140 | foreach ($arr_attributes as $key => $value) { |
140 | $model->addRule($key, 'in', ['range' => array_keys(Yii::$app->multiparser->getConfiguration('csv', 'basic_column'))]); | 141 | $model->addRule($key, 'in', ['range' => array_keys(Yii::$app->multiparser->getConfiguration('csv', 'basic_column'))]); |
141 | } | 142 | } |
142 | 143 | ||
144 | + // установим режим проверки обязательных полей | ||
145 | + $details_model->setScenario('form_upload_validation'); | ||
146 | + $model_validator = new ModelArrayValidator( $details_model ); | ||
143 | // провалидируем выбранные колонки | 147 | // провалидируем выбранные колонки |
144 | - if ($model->validate()) { | 148 | + if ( $model->validate() && $model_validator->validateRow( array_flip( $arr_attributes ) ) ) { |
145 | 149 | ||
146 | // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы | 150 | // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы |
147 | $arr = $model->toArray(); | 151 | $arr = $model->toArray(); |
@@ -164,12 +168,21 @@ class ParserController extends BaseController | @@ -164,12 +168,21 @@ class ParserController extends BaseController | ||
164 | 168 | ||
165 | if( file_exists($configuration['file_path']) ) | 169 | if( file_exists($configuration['file_path']) ) |
166 | unlink($configuration['file_path']); | 170 | unlink($configuration['file_path']); |
167 | - | ||
168 | - Yii::$app->session->setFlash( $writer->getValidatedTypeMsg(), $writer->getValidatedMsg() ); | 171 | + $validated_type_msg = $writer->hasValidationError() ? 'warning' : 'success'; |
172 | + Yii::$app->session->setFlash( $validated_type_msg, $writer->getValidatedMsg() ); | ||
169 | return $this->render('index', ['model' => $configuration]); | 173 | return $this->render('index', ['model' => $configuration]); |
170 | 174 | ||
171 | }; | 175 | }; |
172 | 176 | ||
177 | + } else { | ||
178 | + // не прошла валидация формы загрузки файлов | ||
179 | + $errors_str = "Ошибка валидации формы загрузки файлов. "; | ||
180 | + | ||
181 | + foreach ( $details_model->getErrors() as $error ) { | ||
182 | + $errors_str .= implode(array_values($error)); | ||
183 | + } | ||
184 | + | ||
185 | + throw new \ErrorException($errors_str); | ||
173 | } | 186 | } |
174 | 187 | ||
175 | } | 188 | } |
@@ -199,7 +212,7 @@ class ParserController extends BaseController | @@ -199,7 +212,7 @@ class ParserController extends BaseController | ||
199 | $arr_id_files[] = (int) $file_id; | 212 | $arr_id_files[] = (int) $file_id; |
200 | } | 213 | } |
201 | 214 | ||
202 | - $query = ImportersFiles::find()->where(['in', 'id', $arr_id_files])->orderBy(['upload_time' => SORT_DESC]); | 215 | + $query = ImportersFiles::find()->where(['in', 'id', $arr_id_files])->orderBy( ['upload_time' => SORT_DESC] ); |
203 | 216 | ||
204 | $provider = new ActiveDataProvider([ | 217 | $provider = new ActiveDataProvider([ |
205 | 'query' => $query, | 218 | 'query' => $query, |
backend/controllers/RgGrupController.php
@@ -11,6 +11,7 @@ namespace backend\controllers; | @@ -11,6 +11,7 @@ namespace backend\controllers; | ||
11 | use backend\components\base\BaseController; | 11 | use backend\components\base\BaseController; |
12 | use backend\models\UploadFileRgForm; | 12 | use backend\models\UploadFileRgForm; |
13 | use common\components\CustomVarDamp; | 13 | use common\components\CustomVarDamp; |
14 | +use common\components\ModelArrayValidator; | ||
14 | use common\components\parsers\MailAttachmentsSaver; | 15 | use common\components\parsers\MailAttachmentsSaver; |
15 | use common\models\Margins; | 16 | use common\models\Margins; |
16 | use common\models\MarginsGroups; | 17 | use common\models\MarginsGroups; |
@@ -117,15 +118,18 @@ class RgGrupController extends BaseController | @@ -117,15 +118,18 @@ class RgGrupController extends BaseController | ||
117 | { | 118 | { |
118 | //получим колонки которые выбрал пользователь | 119 | //получим колонки которые выбрал пользователь |
119 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; | 120 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; |
121 | + $margin_model = new MarginsGroups(); | ||
120 | //соберем модель по полученным данным | 122 | //соберем модель по полученным данным |
121 | $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); | 123 | $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); |
122 | //добавим правила валидации (колонки должны быть те что в модели) | 124 | //добавим правила валидации (колонки должны быть те что в модели) |
123 | foreach ($arr_attributes as $key => $value) { | 125 | foreach ($arr_attributes as $key => $value) { |
124 | $model->addRule($key, 'in', ['range' => array_keys(Margins::getHeader())]); | 126 | $model->addRule($key, 'in', ['range' => array_keys(Margins::getHeader())]); |
125 | } | 127 | } |
126 | - | 128 | + // установим режим проверки обязательных полей |
129 | + $margin_model->setScenario('form_upload_validation'); | ||
130 | + $model_validator = new ModelArrayValidator( $margin_model ); | ||
127 | // провалидируем выбранные колонки | 131 | // провалидируем выбранные колонки |
128 | - if ( $model->validate() ) { | 132 | + if ( $model->validate() && $model_validator->validateRow( array_flip( $arr_attributes ) )) { |
129 | 133 | ||
130 | // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы | 134 | // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы |
131 | $arr = $model->toArray(); | 135 | $arr = $model->toArray(); |
@@ -170,26 +174,38 @@ class RgGrupController extends BaseController | @@ -170,26 +174,38 @@ class RgGrupController extends BaseController | ||
170 | $row['margin_id'] = ltrim($key, '!'); | 174 | $row['margin_id'] = ltrim($key, '!'); |
171 | $row['koef'] = \Yii::$app->converter->convertTo('float', $value, ['precision' => 6]); | 175 | $row['koef'] = \Yii::$app->converter->convertTo('float', $value, ['precision' => 6]); |
172 | 176 | ||
173 | - | ||
174 | $arr_values[] = $row; | 177 | $arr_values[] = $row; |
175 | - | ||
176 | } | 178 | } |
177 | - | ||
178 | } | 179 | } |
180 | + unset($data); | ||
181 | + // валидируем отпарсенные данные моделью в которую будем записывать | ||
182 | + $margin_model->setScenario('default'); | ||
183 | + $arr_values = $model_validator->validate( $arr_values ); | ||
184 | + $msg = $model_validator->getMassage(); | ||
185 | + $type_msg = $model_validator->hasError() ? 'warning' : 'success'; | ||
186 | + $model_validator->close(); | ||
179 | // сохраним подготовленные данные | 187 | // сохраним подготовленные данные |
180 | - MarginsGroups::ManualInsertWithUpdate( $arr_values, [ 'group','importer_id','margin_id' ] ); | ||
181 | - | ||
182 | - | ||
183 | - Yii::$app->session->setFlash('success', "Файл {$configuration['file']} успешно загружен"); | ||
184 | - // все прошло успешно - очищаем кеш | ||
185 | - Yii::$app->getCache()->delete('parser_data'); | ||
186 | - Yii::$app->getCache()->delete('parser_configuration'); | 188 | + if ( !empty( $arr_values ) ) { |
189 | + MarginsGroups::ManualInsertWithUpdate( $arr_values, [ 'group','importer_id','margin_id' ] ); | ||
190 | + // все прошло успешно - очищаем кеш | ||
191 | + Yii::$app->getCache()->delete('parser_data'); | ||
192 | + Yii::$app->getCache()->delete('parser_configuration'); | ||
193 | + | ||
194 | + if (file_exists($configuration['file_path'])) | ||
195 | + unlink($configuration['file_path']); | ||
196 | + } | ||
187 | 197 | ||
188 | - if (file_exists($configuration['file_path'])) | ||
189 | - unlink($configuration['file_path']); | ||
190 | 198 | ||
199 | + Yii::$app->session->setFlash( $type_msg, $msg ); | ||
191 | return $this->render('index', ['model' => $configuration]); | 200 | return $this->render('index', ['model' => $configuration]); |
192 | 201 | ||
202 | + } else { | ||
203 | + // не прошла валидация формы загрузки файлов | ||
204 | + $errors_str = "Ошибка валидации формы загрузки файлов. "; | ||
205 | + foreach ($margin_model->getErrors() as $error) { | ||
206 | + $errors_str .= implode(array_values($error)); | ||
207 | + } | ||
208 | + throw new \ErrorException($errors_str); | ||
193 | } | 209 | } |
194 | 210 | ||
195 | } | 211 | } |
backend/models/Details.php
@@ -55,13 +55,13 @@ class Details extends BaseActiveRecord | @@ -55,13 +55,13 @@ class Details extends BaseActiveRecord | ||
55 | public function rules() | 55 | public function rules() |
56 | { | 56 | { |
57 | return [ | 57 | return [ |
58 | - [['BRAND', 'ARTICLE', 'PRICE', 'DESCR', 'BOX'], 'required'], | ||
59 | - [['PRICE'], 'number'], | ||
60 | - [['BOX'], 'integer'], | ||
61 | - [['timestamp'], 'safe'], | ||
62 | - [['BRAND', 'ARTICLE'], 'string', 'max' => 100], | ||
63 | - [['FULL_ARTICLE'], 'string', 'max' => 150], | ||
64 | - [['DESCR', 'GROUP'], 'string', 'max' => 200] | 58 | + [['BRAND', 'ARTICLE', 'PRICE', 'DESCR', 'BOX'], 'required' , 'on' => ['default','form_upload_validation']], |
59 | + [['PRICE'], 'number', 'on' => 'default'], | ||
60 | + [['BOX'], 'integer' , 'on' => 'default'], | ||
61 | + [['timestamp'], 'safe' , 'on' => 'default'], | ||
62 | + [['BRAND', 'ARTICLE'], 'string', 'max' => 100 , 'on' => 'default'], | ||
63 | + [['FULL_ARTICLE'], 'string', 'max' => 150 , 'on' => 'default'], | ||
64 | + [['DESCR', 'GROUP'], 'string', 'max' => 200 , 'on' => 'default'] | ||
65 | ]; | 65 | ]; |
66 | } | 66 | } |
67 | 67 |
backend/models/DetailsCrosses.php
@@ -35,9 +35,9 @@ class DetailsCrosses extends \backend\components\base\BaseActiveRecord | @@ -35,9 +35,9 @@ class DetailsCrosses extends \backend\components\base\BaseActiveRecord | ||
35 | public function rules() | 35 | public function rules() |
36 | { | 36 | { |
37 | return [ | 37 | return [ |
38 | - [['ARTICLE', 'BRAND', 'CROSS_BRAND', 'CROSS_ARTICLE'], 'required'], | ||
39 | - [['timestamp'], 'safe'], | ||
40 | - [['ARTICLE', 'BRAND', 'CROSS_BRAND', 'CROSS_ARTICLE'], 'string', 'max' => 100] | 38 | + [['ARTICLE', 'BRAND', 'CROSS_BRAND', 'CROSS_ARTICLE'], 'required', 'on' => ['default','form_upload_validation']], |
39 | + [['timestamp'], 'safe' , 'on' => 'default'], | ||
40 | + [['ARTICLE', 'BRAND', 'CROSS_BRAND', 'CROSS_ARTICLE'], 'string', 'max' => 100 , 'on' => 'default'] | ||
41 | ]; | 41 | ]; |
42 | } | 42 | } |
43 | 43 |
backend/models/Details_old.php deleted
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(); | ||
136 | \ No newline at end of file | 0 | \ No newline at end of file |
backend/models/Importers.php
@@ -96,13 +96,13 @@ class Importers extends BaseActiveRecord | @@ -96,13 +96,13 @@ class Importers extends BaseActiveRecord | ||
96 | $arr = $this->toArray(); | 96 | $arr = $this->toArray(); |
97 | 97 | ||
98 | // отсортируем по ключам с учетом преобразования в число | 98 | // отсортируем по ключам с учетом преобразования в число |
99 | - asort($arr, SORT_NUMERIC); | 99 | + //asort($arr, SORT_NUMERIC); |
100 | // уберем нулевые колонки | 100 | // уберем нулевые колонки |
101 | $arr = array_filter($arr, function($val){ | 101 | $arr = array_filter($arr, function($val){ |
102 | return $val <> '0'; | 102 | return $val <> '0'; |
103 | }); | 103 | }); |
104 | - // нам нужны именно ключи | ||
105 | - $arr = array_keys($arr); | 104 | + // нам нужны именно массив в виде 'номер колонки в файле'=>'имя колонки в БД' |
105 | + $arr = array_flip( $arr ); | ||
106 | 106 | ||
107 | return $arr; | 107 | return $arr; |
108 | } | 108 | } |
backend/views/rg-grup/index.php
@@ -11,10 +11,6 @@ $button_label = 'Прочитать'; | @@ -11,10 +11,6 @@ $button_label = 'Прочитать'; | ||
11 | <div class="row"> | 11 | <div class="row"> |
12 | <div class="col-lg-5"> | 12 | <div class="col-lg-5"> |
13 | <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data',],'action'=>['rg-grup/results']]); | 13 | <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data',],'action'=>['rg-grup/results']]); |
14 | - | ||
15 | - if ($msg = \Yii::$app->session->getFlash('success')) { // вернулись после успешной загрузки данного файла | ||
16 | - echo Html::tag('h3', $msg ,['class'=>'bg-success']); | ||
17 | - } | ||
18 | ?> | 14 | ?> |
19 | <h3>Загрузка RG групп поставщиков</h3> | 15 | <h3>Загрузка RG групп поставщиков</h3> |
20 | 16 | ||
@@ -27,7 +23,9 @@ $button_label = 'Прочитать'; | @@ -27,7 +23,9 @@ $button_label = 'Прочитать'; | ||
27 | <?= Html::submitButton(Yii::t( 'app', $button_label ), ['class' => 'btn btn-primary']) ?> | 23 | <?= Html::submitButton(Yii::t( 'app', $button_label ), ['class' => 'btn btn-primary']) ?> |
28 | </div> | 24 | </div> |
29 | 25 | ||
30 | - <?php ActiveForm::end() ?> | 26 | + <?php ActiveForm::end(); |
27 | + // подключим шаблон сообщения | ||
28 | + echo $this->render('../templates/parser_massage');?> | ||
31 | </div> | 29 | </div> |
32 | </div> | 30 | </div> |
33 | 31 |
common/components/ModelArrayValidator.php
@@ -76,20 +76,33 @@ class ModelArrayValidator | @@ -76,20 +76,33 @@ class ModelArrayValidator | ||
76 | { | 76 | { |
77 | foreach ( $data as $row ) { | 77 | foreach ( $data as $row ) { |
78 | $this->total_rows++; | 78 | $this->total_rows++; |
79 | - $validate_row[$this->model->formName()] = $row; | ||
80 | - // clear previous loading | ||
81 | - $this->clearModelAttributes(); | ||
82 | - if ( $this->model->load( $validate_row ) && $this->model->validate() ) { | 79 | + |
80 | + if ( $this->validateRow( $row ) ) { | ||
83 | // everything OK, registred row to valid data | 81 | // everything OK, registred row to valid data |
84 | $this->valid_data[] = $row; | 82 | $this->valid_data[] = $row; |
85 | } else{ | 83 | } else{ |
86 | // we have errors | 84 | // we have errors |
87 | $this->registredError( $this->total_rows ); | 85 | $this->registredError( $this->total_rows ); |
88 | } | 86 | } |
87 | + | ||
89 | } | 88 | } |
90 | 89 | ||
91 | return $this->valid_data; | 90 | return $this->valid_data; |
92 | } | 91 | } |
92 | + public function validateRow( $row ) | ||
93 | + { | ||
94 | + $validate_row[$this->model->formName()] = $row; | ||
95 | + // clear previous loading | ||
96 | + $this->clearModelAttributes(); | ||
97 | + if ( $this->model->load( $validate_row ) && $this->model->validate() ) { | ||
98 | + | ||
99 | + return true; | ||
100 | + } else{ | ||
101 | + | ||
102 | + return false; | ||
103 | + } | ||
104 | + | ||
105 | + } | ||
93 | 106 | ||
94 | protected function registredError ($index) | 107 | protected function registredError ($index) |
95 | { | 108 | { |
@@ -117,11 +130,17 @@ class ModelArrayValidator | @@ -117,11 +130,17 @@ class ModelArrayValidator | ||
117 | 130 | ||
118 | } | 131 | } |
119 | 132 | ||
133 | + public function clearErrors(){ | ||
134 | + | ||
135 | + $this->arr_errors = []; | ||
136 | + | ||
137 | + } | ||
138 | + | ||
120 | public function close(){ | 139 | public function close(){ |
121 | 140 | ||
122 | - unset( $this->valid_data ); | ||
123 | - unset( $this->arr_errors ); | ||
124 | - unset( $this->model ); | 141 | + $this->valid_data = []; |
142 | + $this->clearErrors(); | ||
143 | + $this->total_rows = 0; | ||
125 | 144 | ||
126 | } | 145 | } |
127 | } | 146 | } |
128 | \ No newline at end of file | 147 | \ No newline at end of file |
common/components/PriceWriter.php
@@ -43,15 +43,15 @@ class PriceWriter | @@ -43,15 +43,15 @@ class PriceWriter | ||
43 | */ | 43 | */ |
44 | protected $validated_msg; | 44 | protected $validated_msg; |
45 | /** | 45 | /** |
46 | - * @var - тип сообщения валидатора - success, warning | 46 | + * @var - bool - есть ли ошибки валидации |
47 | */ | 47 | */ |
48 | - protected $validated_type_msg; | 48 | + protected $hasValidationError; |
49 | 49 | ||
50 | 50 | ||
51 | 51 | ||
52 | function __construct() | 52 | function __construct() |
53 | { | 53 | { |
54 | - set_time_limit(300); | 54 | + set_time_limit(600); |
55 | } | 55 | } |
56 | 56 | ||
57 | /** | 57 | /** |
@@ -89,9 +89,9 @@ class PriceWriter | @@ -89,9 +89,9 @@ class PriceWriter | ||
89 | /** | 89 | /** |
90 | * @return mixed | 90 | * @return mixed |
91 | */ | 91 | */ |
92 | - public function getValidatedTypeMsg() | 92 | + public function hasValidationError() |
93 | { | 93 | { |
94 | - return $this->validated_type_msg; | 94 | + return $this->hasValidationError; |
95 | } | 95 | } |
96 | 96 | ||
97 | 97 | ||
@@ -117,12 +117,16 @@ class PriceWriter | @@ -117,12 +117,16 @@ class PriceWriter | ||
117 | } | 117 | } |
118 | //3. провалидируем полученные данные моделью - Details | 118 | //3. провалидируем полученные данные моделью - Details |
119 | $details_model = $this->validateByDetailsModel(); | 119 | $details_model = $this->validateByDetailsModel(); |
120 | + if ( empty($this->data) ) { | ||
121 | + // после валидации не осталось валидных данных для записи | ||
122 | + return false; | ||
123 | + } | ||
124 | + //4. дополним данные значением импортера и даты обновления цены | ||
125 | + $this->data = CustomArrayHelper::addColumns($this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date]); | ||
120 | 126 | ||
121 | - //4. дополним данные значением импортера и даты обновления цены | ||
122 | - $this->data = CustomArrayHelper::addColumns($this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date]); | 127 | + //5. запишем данные в связанные таблицы |
128 | + $this->writePriceInTransaction($details_model, $files_model, $update_date); | ||
123 | 129 | ||
124 | - //5. запишем данные в связанные таблицы | ||
125 | - $this->writePriceInTransaction($details_model, $files_model, $update_date); | ||
126 | 130 | ||
127 | return true; | 131 | return true; |
128 | } | 132 | } |
@@ -255,7 +259,7 @@ class PriceWriter | @@ -255,7 +259,7 @@ class PriceWriter | ||
255 | $model_validator = new ModelArrayValidator( $details_model ); | 259 | $model_validator = new ModelArrayValidator( $details_model ); |
256 | $this->data = $model_validator->validate( $this->data ); | 260 | $this->data = $model_validator->validate( $this->data ); |
257 | $this->validated_msg = $model_validator->getMassage(); | 261 | $this->validated_msg = $model_validator->getMassage(); |
258 | - $this->validated_type_msg = $model_validator->hasError() ? 'warning' : 'success'; | 262 | + $this->hasValidationError = $model_validator->hasError(); |
259 | 263 | ||
260 | $model_validator->close(); | 264 | $model_validator->close(); |
261 | 265 |
common/components/parsers/config.php
@@ -6,7 +6,8 @@ | @@ -6,7 +6,8 @@ | ||
6 | 'auto_detect_first_line' => true, | 6 | 'auto_detect_first_line' => true, |
7 | 'converter_conf' => [ | 7 | 'converter_conf' => [ |
8 | 'class' => 'common\components\parsers\CustomConverter', | 8 | 'class' => 'common\components\parsers\CustomConverter', |
9 | - 'configuration' => ["encode" => 'DESCR'],] | 9 | + 'configuration' => ["encode" => 'DESCR'], |
10 | + ] | ||
10 | ], | 11 | ], |
11 | 'console' => | 12 | 'console' => |
12 | ['class' => 'common\components\parsers\CustomCsvParser', | 13 | ['class' => 'common\components\parsers\CustomCsvParser', |
@@ -39,7 +40,6 @@ | @@ -39,7 +40,6 @@ | ||
39 | 'crosses' => ['class' => 'common\components\parsers\CustomCsvParser', | 40 | 'crosses' => ['class' => 'common\components\parsers\CustomCsvParser', |
40 | 'auto_detect_first_line' => true, | 41 | 'auto_detect_first_line' => true, |
41 | 'min_column_quantity' => 4, | 42 | 'min_column_quantity' => 4, |
42 | - // 'keys' =>['ARTICLE', 'CROSS_ARTICLE', 'BRAND', 'CROSS_BRAND'], | ||
43 | 'converter_conf' => [ | 43 | 'converter_conf' => [ |
44 | 'class' => ' common\components\parsers\CustomConverter', | 44 | 'class' => ' common\components\parsers\CustomConverter', |
45 | 'hasKey' => 1, | 45 | 'hasKey' => 1, |
common/models/MarginsGroups.php
@@ -31,12 +31,12 @@ class MarginsGroups extends \yii\db\ActiveRecord | @@ -31,12 +31,12 @@ class MarginsGroups extends \yii\db\ActiveRecord | ||
31 | public function rules() | 31 | public function rules() |
32 | { | 32 | { |
33 | return [ | 33 | return [ |
34 | - [['importer_id', 'margin_id', 'group', 'koef'], 'required'], | ||
35 | - [['importer_id', 'margin_id'], 'integer'], | ||
36 | - [['koef'], 'number'], | ||
37 | - [['timestamp'], 'safe'], | ||
38 | - [['group'], 'string', 'max' => 200], | ||
39 | - [['importer_id', 'margin_id', 'group'], 'unique', 'targetAttribute' => ['importer_id', 'margin_id', 'group'], 'message' => 'The combination of Importer ID, Margin ID and Group has already been taken.'] | 34 | + [['importer_id', 'margin_id', 'koef'], 'required', 'on' => 'default'], |
35 | + ['group', 'required', 'on' => ['default','form_upload_validation']], | ||
36 | + [['importer_id', 'margin_id'], 'integer' , 'on' => 'default'], | ||
37 | + [['koef'], 'number' , 'on' => 'default'], | ||
38 | + [['timestamp'], 'safe' , 'on' => 'default'], | ||
39 | + [['group'], 'string', 'max' => 200 , 'on' => 'default'], | ||
40 | ]; | 40 | ]; |
41 | } | 41 | } |
42 | 42 |
console/controllers/ParserController.php
@@ -39,7 +39,7 @@ class ParserController extends Controller | @@ -39,7 +39,7 @@ class ParserController extends Controller | ||
39 | 'multiplier' => $multiplier], | 39 | 'multiplier' => $multiplier], |
40 | 'mode' => 'console'] | 40 | 'mode' => 'console'] |
41 | ]; | 41 | ]; |
42 | - if ($this->parseFileConsole($file_path, $config)) { | 42 | + if ( $this->parseFileConsole( $file_path, $config ) ) { |
43 | unlink(\Yii::getAlias('@temp_upload') . '/' . $file_name . '.csv'); | 43 | unlink(\Yii::getAlias('@temp_upload') . '/' . $file_name . '.csv'); |
44 | \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser'); | 44 | \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser'); |
45 | } else { | 45 | } else { |
@@ -71,12 +71,16 @@ class ParserController extends Controller | @@ -71,12 +71,16 @@ class ParserController extends Controller | ||
71 | $writer->setData( $data ); | 71 | $writer->setData( $data ); |
72 | $writer->setMode( 1 ); //console-режим | 72 | $writer->setMode( 1 ); //console-режим |
73 | 73 | ||
74 | - if ( $writer->writePriceToDB() ){ | 74 | + $writer->writePriceToDB(); |
75 | + if ( $writer->hasValidationError() ) { | ||
76 | + \Yii::error( $writer->getValidatedMsg(), 'parser' ); | ||
77 | + }else{ | ||
78 | + \Yii::info( $writer->getValidatedMsg(), 'parser' ); | ||
79 | + } | ||
80 | + | ||
75 | 81 | ||
76 | return true; | 82 | return true; |
77 | - } | ||
78 | 83 | ||
79 | - return false; | ||
80 | } | 84 | } |
81 | 85 | ||
82 | public function actionParseXml () | 86 | public function actionParseXml () |