Commit 209dad04425c8ac8b66042f456a208f0696ccfea

Authored by Mihail
1 parent 9195565b

add validator for requiremetts coloumn in parser forms

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 = &#39;Прочитать&#39;; @@ -11,10 +11,6 @@ $button_label = &#39;Прочитать&#39;;
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 = &#39;Прочитать&#39;; @@ -27,7 +23,9 @@ $button_label = &#39;Прочитать&#39;;
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 ()