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 () | ... | ... |