Commit 7c1201d159494cd1c992555cdb11a98b5715c4f1
1 parent
70eb26db
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 | 116 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; |
117 | 117 | //соберем модель по полученным данным |
118 | 118 | $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); |
119 | + $crosses_model = new DetailsCrosses(); | |
119 | 120 | //добавим правила валидации (колонки должны быть те что в модели) |
120 | 121 | foreach ($arr_attributes as $key => $value) { |
121 | 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 | 131 | $arr = $model->toArray(); |
... | ... | @@ -138,8 +141,7 @@ class CrossingUploadController extends BaseController |
138 | 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 | 145 | $data = $model_validator->validate( $data ); |
144 | 146 | $msg = $model_validator->getMassage(); |
145 | 147 | $type_msg = $model_validator->hasError() ? 'warning' : 'success'; |
... | ... | @@ -162,8 +164,8 @@ class CrossingUploadController extends BaseController |
162 | 164 | |
163 | 165 | } else { |
164 | 166 | // не прошла валидация формы загрузки файлов |
165 | - $errors_str = ''; | |
166 | - foreach ($model->getErrors() as $error) { | |
167 | + $errors_str = "Ошибка валидации формы загрузки файлов. "; | |
168 | + foreach ($crosses_model->getErrors() as $error) { | |
167 | 169 | $errors_str .= implode(array_values($error)); |
168 | 170 | } |
169 | 171 | throw new \ErrorException($errors_str); | ... | ... |
backend/controllers/ParserController.php
1 | 1 | <?php |
2 | 2 | namespace backend\controllers; |
3 | 3 | |
4 | +use backend\models\Details; | |
4 | 5 | use common\components\archives\ArchiveCreator; |
5 | 6 | use common\components\mail\ImapMailReader; |
6 | 7 | use common\components\mail\MailAttachmentsSaver; |
8 | +use common\components\ModelArrayValidator; | |
7 | 9 | use common\components\parsers\MailParser; |
8 | 10 | use Yii; |
9 | 11 | use yii\data\ActiveDataProvider; |
... | ... | @@ -72,14 +74,13 @@ class ParserController extends BaseController |
72 | 74 | |
73 | 75 | public function actionResults($mode = 0) |
74 | 76 | { |
77 | + set_time_limit(600); | |
75 | 78 | $model = new UploadFileParsingForm( ['mode' => $mode] ); |
76 | 79 | $data = []; |
77 | 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 | 84 | if ( $model->validate() ) { |
84 | 85 | // сохраним файл и создадим модель - ImportersFiles |
85 | 86 | $files_model = $this->saveParserFile($model); |
... | ... | @@ -95,12 +96,11 @@ class ParserController extends BaseController |
95 | 96 | |
96 | 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 | 106 | } else if ( Yii::$app->getCache()->get('parser_data') ) { |
... | ... | @@ -135,13 +135,17 @@ class ParserController extends BaseController |
135 | 135 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; |
136 | 136 | //соберем модель по полученным данным |
137 | 137 | $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); |
138 | + $details_model = new Details(); | |
138 | 139 | //добавим правила валидации (колонки должны быть те что указаны в конфиге) |
139 | 140 | foreach ($arr_attributes as $key => $value) { |
140 | 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 | 151 | $arr = $model->toArray(); |
... | ... | @@ -164,12 +168,21 @@ class ParserController extends BaseController |
164 | 168 | |
165 | 169 | if( file_exists($configuration['file_path']) ) |
166 | 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 | 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 | 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 | 217 | $provider = new ActiveDataProvider([ |
205 | 218 | 'query' => $query, | ... | ... |
backend/controllers/RgGrupController.php
... | ... | @@ -11,6 +11,7 @@ namespace backend\controllers; |
11 | 11 | use backend\components\base\BaseController; |
12 | 12 | use backend\models\UploadFileRgForm; |
13 | 13 | use common\components\CustomVarDamp; |
14 | +use common\components\ModelArrayValidator; | |
14 | 15 | use common\components\parsers\MailAttachmentsSaver; |
15 | 16 | use common\models\Margins; |
16 | 17 | use common\models\MarginsGroups; |
... | ... | @@ -117,15 +118,18 @@ class RgGrupController extends BaseController |
117 | 118 | { |
118 | 119 | //получим колонки которые выбрал пользователь |
119 | 120 | $arr_attributes = Yii::$app->request->post()['DynamicModel']; |
121 | + $margin_model = new MarginsGroups(); | |
120 | 122 | //соберем модель по полученным данным |
121 | 123 | $model = DynamicFormHelper::CreateDynamicModel($arr_attributes); |
122 | 124 | //добавим правила валидации (колонки должны быть те что в модели) |
123 | 125 | foreach ($arr_attributes as $key => $value) { |
124 | 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 | 135 | $arr = $model->toArray(); |
... | ... | @@ -170,26 +174,38 @@ class RgGrupController extends BaseController |
170 | 174 | $row['margin_id'] = ltrim($key, '!'); |
171 | 175 | $row['koef'] = \Yii::$app->converter->convertTo('float', $value, ['precision' => 6]); |
172 | 176 | |
173 | - | |
174 | 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 | 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 | 55 | public function rules() |
56 | 56 | { |
57 | 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 | 35 | public function rules() |
36 | 36 | { |
37 | 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 | 0 | \ No newline at end of file |
backend/models/Importers.php
... | ... | @@ -96,13 +96,13 @@ class Importers extends BaseActiveRecord |
96 | 96 | $arr = $this->toArray(); |
97 | 97 | |
98 | 98 | // отсортируем по ключам с учетом преобразования в число |
99 | - asort($arr, SORT_NUMERIC); | |
99 | + //asort($arr, SORT_NUMERIC); | |
100 | 100 | // уберем нулевые колонки |
101 | 101 | $arr = array_filter($arr, function($val){ |
102 | 102 | return $val <> '0'; |
103 | 103 | }); |
104 | - // нам нужны именно ключи | |
105 | - $arr = array_keys($arr); | |
104 | + // нам нужны именно массив в виде 'номер колонки в файле'=>'имя колонки в БД' | |
105 | + $arr = array_flip( $arr ); | |
106 | 106 | |
107 | 107 | return $arr; |
108 | 108 | } | ... | ... |
backend/views/rg-grup/index.php
... | ... | @@ -11,10 +11,6 @@ $button_label = 'Прочитать'; |
11 | 11 | <div class="row"> |
12 | 12 | <div class="col-lg-5"> |
13 | 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 | 15 | <h3>Загрузка RG групп поставщиков</h3> |
20 | 16 | |
... | ... | @@ -27,7 +23,9 @@ $button_label = 'Прочитать'; |
27 | 23 | <?= Html::submitButton(Yii::t( 'app', $button_label ), ['class' => 'btn btn-primary']) ?> |
28 | 24 | </div> |
29 | 25 | |
30 | - <?php ActiveForm::end() ?> | |
26 | + <?php ActiveForm::end(); | |
27 | + // подключим шаблон сообщения | |
28 | + echo $this->render('../templates/parser_massage');?> | |
31 | 29 | </div> |
32 | 30 | </div> |
33 | 31 | ... | ... |
common/components/ModelArrayValidator.php
... | ... | @@ -76,20 +76,33 @@ class ModelArrayValidator |
76 | 76 | { |
77 | 77 | foreach ( $data as $row ) { |
78 | 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 | 81 | // everything OK, registred row to valid data |
84 | 82 | $this->valid_data[] = $row; |
85 | 83 | } else{ |
86 | 84 | // we have errors |
87 | 85 | $this->registredError( $this->total_rows ); |
88 | 86 | } |
87 | + | |
89 | 88 | } |
90 | 89 | |
91 | 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 | 107 | protected function registredError ($index) |
95 | 108 | { |
... | ... | @@ -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 | 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 | 147 | \ No newline at end of file | ... | ... |
common/components/PriceWriter.php
... | ... | @@ -43,15 +43,15 @@ class PriceWriter |
43 | 43 | */ |
44 | 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 | 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 | 89 | /** |
90 | 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 | 117 | } |
118 | 118 | //3. провалидируем полученные данные моделью - Details |
119 | 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 | 131 | return true; |
128 | 132 | } |
... | ... | @@ -255,7 +259,7 @@ class PriceWriter |
255 | 259 | $model_validator = new ModelArrayValidator( $details_model ); |
256 | 260 | $this->data = $model_validator->validate( $this->data ); |
257 | 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 | 264 | $model_validator->close(); |
261 | 265 | ... | ... |
common/components/parsers/config.php
... | ... | @@ -6,7 +6,8 @@ |
6 | 6 | 'auto_detect_first_line' => true, |
7 | 7 | 'converter_conf' => [ |
8 | 8 | 'class' => 'common\components\parsers\CustomConverter', |
9 | - 'configuration' => ["encode" => 'DESCR'],] | |
9 | + 'configuration' => ["encode" => 'DESCR'], | |
10 | + ] | |
10 | 11 | ], |
11 | 12 | 'console' => |
12 | 13 | ['class' => 'common\components\parsers\CustomCsvParser', |
... | ... | @@ -39,7 +40,6 @@ |
39 | 40 | 'crosses' => ['class' => 'common\components\parsers\CustomCsvParser', |
40 | 41 | 'auto_detect_first_line' => true, |
41 | 42 | 'min_column_quantity' => 4, |
42 | - // 'keys' =>['ARTICLE', 'CROSS_ARTICLE', 'BRAND', 'CROSS_BRAND'], | |
43 | 43 | 'converter_conf' => [ |
44 | 44 | 'class' => ' common\components\parsers\CustomConverter', |
45 | 45 | 'hasKey' => 1, | ... | ... |
common/models/MarginsGroups.php
... | ... | @@ -31,12 +31,12 @@ class MarginsGroups extends \yii\db\ActiveRecord |
31 | 31 | public function rules() |
32 | 32 | { |
33 | 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 | 39 | 'multiplier' => $multiplier], |
40 | 40 | 'mode' => 'console'] |
41 | 41 | ]; |
42 | - if ($this->parseFileConsole($file_path, $config)) { | |
42 | + if ( $this->parseFileConsole( $file_path, $config ) ) { | |
43 | 43 | unlink(\Yii::getAlias('@temp_upload') . '/' . $file_name . '.csv'); |
44 | 44 | \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser'); |
45 | 45 | } else { |
... | ... | @@ -71,12 +71,16 @@ class ParserController extends Controller |
71 | 71 | $writer->setData( $data ); |
72 | 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 | 82 | return true; |
77 | - } | |
78 | 83 | |
79 | - return false; | |
80 | 84 | } |
81 | 85 | |
82 | 86 | public function actionParseXml () | ... | ... |