Commit 706a1491d0985e649347f310452e2ce10cffc8ec
1 parent
91c8f898
add form, model and controller for uploaded crosses files (details_crosses
Showing
11 changed files
with
322 additions
and
31 deletions
Show diff stats
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * Created by PhpStorm. | ||
| 4 | + * User: Tsurkanov | ||
| 5 | + * Date: 15.10.2015 | ||
| 6 | + * Time: 12:27 | ||
| 7 | + */ | ||
| 8 | + | ||
| 9 | +namespace backend\controllers; | ||
| 10 | + | ||
| 11 | +use backend\components\base\BaseController; | ||
| 12 | +use common\components\CustomVarDamp; | ||
| 13 | +use yii\filters\AccessControl; | ||
| 14 | +use backend\models\UploadFileCrossingForm; | ||
| 15 | +use backend\models\DetailsCrosses; | ||
| 16 | +use yii\web\UploadedFile; | ||
| 17 | +use \Yii; | ||
| 18 | + | ||
| 19 | +class CrossingUploadController extends BaseController | ||
| 20 | +{ | ||
| 21 | + public $layout = "/column"; | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * @inheritdoc | ||
| 25 | + */ | ||
| 26 | + public function behaviors() | ||
| 27 | + { | ||
| 28 | + return [ | ||
| 29 | + 'access' => [ | ||
| 30 | + 'class' => AccessControl::className(), | ||
| 31 | + 'rules' => [ | ||
| 32 | + [ | ||
| 33 | + 'actions' => ['index', 'result'], | ||
| 34 | + 'allow' => true, | ||
| 35 | + 'roles' => ['@'], | ||
| 36 | + ], | ||
| 37 | + ], | ||
| 38 | + ], | ||
| 39 | +// 'verbs' => [ | ||
| 40 | +// 'class' => VerbFilter::className(), | ||
| 41 | +// 'actions' => [ | ||
| 42 | +// 'logout' => ['post'], | ||
| 43 | +// ], | ||
| 44 | +// ], | ||
| 45 | + ]; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * @inheritdoc | ||
| 50 | + */ | ||
| 51 | + public function actions() | ||
| 52 | + { | ||
| 53 | + return [ | ||
| 54 | + 'error' => [ | ||
| 55 | + 'class' => 'yii\web\ErrorAction', | ||
| 56 | + ], | ||
| 57 | + ]; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + | ||
| 61 | + public function actionIndex() | ||
| 62 | + { | ||
| 63 | + $model = new UploadFileCrossingForm(); | ||
| 64 | + return $this->render('index', ['model' => $model]); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + public function actionResult() | ||
| 68 | + { | ||
| 69 | + $model = new UploadFileCrossingForm(); | ||
| 70 | + $data = []; | ||
| 71 | + if ($model->load(Yii::$app->request->post())) { | ||
| 72 | + $model->file = UploadedFile::getInstance($model, 'file'); | ||
| 73 | + | ||
| 74 | + if ($model->validate()) { | ||
| 75 | + $file_name = $model->file->name; | ||
| 76 | + $model->file_path = Yii::getAlias('@temp_upload') . '/' . $file_name; | ||
| 77 | + | ||
| 78 | + $model->file->saveAs($model->file_path); | ||
| 79 | + //запускаем парсинг | ||
| 80 | + // доп. опции для парсера - удаление префикса в артикулах | ||
| 81 | + $options['mode'] = 'crosses'; | ||
| 82 | + $fields = []; | ||
| 83 | + if ($model->delete_prefix1) { | ||
| 84 | + $fields[] = 'ARTICLE'; | ||
| 85 | + } | ||
| 86 | + if ($model->delete_prefix2) { | ||
| 87 | + $fields[] = 'CROSS_ARTICLE'; | ||
| 88 | + } | ||
| 89 | + if ( $fields ) { | ||
| 90 | + $options [ 'converter_conf' ] = [ 'configuration' => [ "article" => $fields , | ||
| 91 | + "string" => ['ARTICLE', 'CROSS_ARTICLE'],] ]; | ||
| 92 | + } else { | ||
| 93 | + $options [ 'converter_conf' ] = [ 'configuration' => [ "string" => ['ARTICLE', 'CROSS_ARTICLE'], ] ]; | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + $data = $model->readFile( $options ); | ||
| 97 | + $crosses_model = new DetailsCrosses(); | ||
| 98 | + $crosses_model->ManualInsertWithIgnore( $data ); | ||
| 99 | + | ||
| 100 | + Yii::$app->session->setFlash('success', 'Файл кроссов успешно загружен'); | ||
| 101 | + return $this->render('index', ['model' => $model]); | ||
| 102 | + }else{ | ||
| 103 | + // не прошла валидация форма загрузки файлов | ||
| 104 | + $errors_str = ''; | ||
| 105 | + foreach ($model->getErrors() as $error) { | ||
| 106 | + $errors_str .= implode( array_values($error) ); | ||
| 107 | + } | ||
| 108 | + throw new \ErrorException( $errors_str ); | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + } else { | ||
| 112 | + throw new \ErrorException( 'Ошибка загрузки данных' ); | ||
| 113 | + } | ||
| 114 | + } | ||
| 115 | +} | ||
| 0 | \ No newline at end of file | 116 | \ No newline at end of file |
backend/controllers/ParserController.php
| @@ -10,7 +10,6 @@ use backend\models\UploadFileParsingForm; | @@ -10,7 +10,6 @@ use backend\models\UploadFileParsingForm; | ||
| 10 | use yii\web\UploadedFile; | 10 | use yii\web\UploadedFile; |
| 11 | use yii\data\ArrayDataProvider; | 11 | use yii\data\ArrayDataProvider; |
| 12 | use yii\multiparser\DynamicFormHelper; | 12 | use yii\multiparser\DynamicFormHelper; |
| 13 | -use backend\components\parsers\CustomParserConfigurator; | ||
| 14 | use backend\models\ImportersFiles; | 13 | use backend\models\ImportersFiles; |
| 15 | use backend\models\Importers; | 14 | use backend\models\Importers; |
| 16 | use yii\base\ErrorException; | 15 | use yii\base\ErrorException; |
backend/models/DetailsCrosses.php
| @@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
| 2 | 2 | ||
| 3 | namespace backend\models; | 3 | namespace backend\models; |
| 4 | 4 | ||
| 5 | +use common\components\CustomVarDamp; | ||
| 5 | use Yii; | 6 | use Yii; |
| 6 | 7 | ||
| 7 | /** | 8 | /** |
| @@ -17,6 +18,10 @@ use Yii; | @@ -17,6 +18,10 @@ use Yii; | ||
| 17 | class DetailsCrosses extends \backend\components\base\BaseActiveRecord | 18 | class DetailsCrosses extends \backend\components\base\BaseActiveRecord |
| 18 | { | 19 | { |
| 19 | /** | 20 | /** |
| 21 | + * int - размер пакета запроса | ||
| 22 | + */ | ||
| 23 | + const BATCH = 1000; | ||
| 24 | + /** | ||
| 20 | * @inheritdoc | 25 | * @inheritdoc |
| 21 | */ | 26 | */ |
| 22 | public static function tableName() | 27 | public static function tableName() |
| @@ -50,4 +55,31 @@ class DetailsCrosses extends \backend\components\base\BaseActiveRecord | @@ -50,4 +55,31 @@ class DetailsCrosses extends \backend\components\base\BaseActiveRecord | ||
| 50 | 'timestamp' => Yii::t('app', 'Timestamp'), | 55 | 'timestamp' => Yii::t('app', 'Timestamp'), |
| 51 | ]; | 56 | ]; |
| 52 | } | 57 | } |
| 58 | + | ||
| 59 | + /** | ||
| 60 | + * вставка данных с игнором дублей прямым запросом SQL | ||
| 61 | + * @param $data - массив вставляемых данный, вставка будет прозводится пакетами размером указанным в константе BATCH | ||
| 62 | + * @throws \yii\db\Exception | ||
| 63 | + */ | ||
| 64 | + //@todo - вынести все ручные инсерты в отдельный класс | ||
| 65 | + public function ManualInsertWithIgnore( $data ) | ||
| 66 | + { | ||
| 67 | + // \common\components\CustomVarDamp::dumpAndDie($data); | ||
| 68 | + $table_name = self::tableName(); | ||
| 69 | + $keys_arr = array_keys($data[0]); | ||
| 70 | + | ||
| 71 | + // запросы будем выполнять пакетами | ||
| 72 | + // размер пакета установлен в константе | ||
| 73 | + // разобъем массив на пакеты и будем их проходить | ||
| 74 | + $data = array_chunk($data, $this::BATCH); | ||
| 75 | + foreach ($data as $current_batch_array) { | ||
| 76 | + | ||
| 77 | + //воспользуемся пакетной вставкой от фреймворка | ||
| 78 | + $query = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $current_batch_array)->sql; | ||
| 79 | + // добавим ключевое слово - ignore | ||
| 80 | + $query = preg_replace('/INSERT/','INSERT IGNORE', $query); | ||
| 81 | + Yii::$app->db->createCommand($query)->execute(); | ||
| 82 | + | ||
| 83 | + } | ||
| 84 | + } | ||
| 53 | } | 85 | } |
| 1 | +<?php | ||
| 2 | +namespace backend\models; | ||
| 3 | + | ||
| 4 | +use yii\base\ErrorException; | ||
| 5 | +use yii\base\Model; | ||
| 6 | +use yii\web\UploadedFile; | ||
| 7 | +use Yii; | ||
| 8 | +use common\components\CustomVarDamp; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * UploadForm is the model behind the upload form. | ||
| 12 | + */ | ||
| 13 | +class UploadFileCrossingForm extends Model | ||
| 14 | +{ | ||
| 15 | + /** | ||
| 16 | + * @var UploadedFile file attribute | ||
| 17 | + */ | ||
| 18 | + // атрибуты формы | ||
| 19 | + public $file; | ||
| 20 | + public $delete_prefix1; | ||
| 21 | + public $delete_prefix2; | ||
| 22 | + public $file_path; | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + public function rules() | ||
| 27 | + { | ||
| 28 | + return [ | ||
| 29 | + ['file', 'required', 'message' => 'Не выбран файл!' ], | ||
| 30 | + [['file'], 'file', 'extensions' => 'csv', 'checkExtensionByMimeType'=>false ], | ||
| 31 | + [['delete_prefix1', 'delete_prefix2'], 'boolean' ], | ||
| 32 | + | ||
| 33 | + ]; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public function attributeLabels() | ||
| 37 | + { | ||
| 38 | + return [ | ||
| 39 | + 'file' => Yii::t('app', 'Источник'), | ||
| 40 | + 'delete_prefix1' => Yii::t('app', 'Удалять префикс в артикуле товара 1'), | ||
| 41 | + 'delete_prefix2' => Yii::t('app', 'Удалять префикс в артикуле товара 2'), | ||
| 42 | + ]; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + public function readFile( $options = [] ){ | ||
| 46 | + | ||
| 47 | + $data = Yii::$app->multiparser->parse( $this->file_path, $options ); | ||
| 48 | + if( !is_array( $data ) ){ | ||
| 49 | + throw new ErrorException("Ошибка чтения из файла кроссов {$this->file_path}"); | ||
| 50 | + } | ||
| 51 | + // файл больше не нужен - данные прочитаны и сохранены в кеш | ||
| 52 | + if( file_exists($this->file_path) ) | ||
| 53 | + unlink($this->file_path); | ||
| 54 | + | ||
| 55 | + return $data; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + public function fields() | ||
| 59 | + { | ||
| 60 | + return [ | ||
| 61 | + | ||
| 62 | + 'delete_price1', | ||
| 63 | + 'delete_price2' | ||
| 64 | + | ||
| 65 | + ]; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + | ||
| 69 | +} | ||
| 0 | \ No newline at end of file | 70 | \ No newline at end of file |
backend/models/UploadFileParsingForm.php
| @@ -48,9 +48,7 @@ class UploadFileParsingForm extends Model | @@ -48,9 +48,7 @@ class UploadFileParsingForm extends Model | ||
| 48 | return [ | 48 | return [ |
| 49 | ['importer_id', 'required', 'message' => 'Не указан поставщик!' ], | 49 | ['importer_id', 'required', 'message' => 'Не указан поставщик!' ], |
| 50 | ['file', 'required', 'message' => 'Не выбран файл!' ], | 50 | ['file', 'required', 'message' => 'Не выбран файл!' ], |
| 51 | - //@todo - not working this file validator!!! - fixed | ||
| 52 | - [['file'], 'file'],// 'extensions' => ['csv', 'xml'] ], | ||
| 53 | - // 'wrongMimeType' => 'Указан неподдерживаемый тип файла. Можно выбирать csv, xml файлы.' ], | 51 | + [['file'], 'file', 'extensions' => ['csv', 'xml'], 'checkExtensionByMimeType'=>false ], |
| 54 | ['importer_id', 'integer','max' => 999999, 'min' => 0 ], | 52 | ['importer_id', 'integer','max' => 999999, 'min' => 0 ], |
| 55 | [['action','delete_prefix', 'delete_price', 'success'], 'boolean', 'except' => 'auto' ], // только для ручной загрузки | 53 | [['action','delete_prefix', 'delete_price', 'success'], 'boolean', 'except' => 'auto' ], // только для ручной загрузки |
| 56 | ['delimiter', 'string', 'max' => 1], | 54 | ['delimiter', 'string', 'max' => 1], |
| 1 | +<?php | ||
| 2 | +use yii\widgets\ActiveForm; | ||
| 3 | +use yii\helpers\Html; | ||
| 4 | +use yii\helpers\ArrayHelper; | ||
| 5 | + | ||
| 6 | +?> | ||
| 7 | +<div class="row"> | ||
| 8 | + <div class="col-lg-5"> | ||
| 9 | + <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data',],'action'=>['crossing-upload/result']]); | ||
| 10 | + | ||
| 11 | + if ($msg = \Yii::$app->session->getFlash('success')) { // вернулись после успешной загрузки данного файла | ||
| 12 | + echo Html::tag('h3', $msg ,['class'=>'bg-success']); | ||
| 13 | + } | ||
| 14 | + ?> | ||
| 15 | + <h3>Кросс файлы</h3> | ||
| 16 | + | ||
| 17 | + <?= $form->field($model, 'delete_prefix1')->checkbox() ?> | ||
| 18 | + <?= $form->field($model, 'delete_prefix2')->checkbox() ?> | ||
| 19 | + <?= $form->field($model, 'file')->fileInput()->label(false) ?> | ||
| 20 | + | ||
| 21 | + <div class="form-group"> | ||
| 22 | + <?= Html::submitButton(Yii::t( 'app', 'Выполнить' ), ['class' => 'btn btn-primary']) ?> | ||
| 23 | + </div> | ||
| 24 | + | ||
| 25 | + <?php ActiveForm::end() ?> | ||
| 26 | + </div> | ||
| 27 | +</div> | ||
| 28 | + |
backend/views/layouts/column.php
| @@ -283,6 +283,7 @@ $this->beginContent('@app/views/layouts/main.php'); | @@ -283,6 +283,7 @@ $this->beginContent('@app/views/layouts/main.php'); | ||
| 283 | 'options' => ['class' => 'sidebar-menu'], | 283 | 'options' => ['class' => 'sidebar-menu'], |
| 284 | 'items' => [ | 284 | 'items' => [ |
| 285 | ['label' => "Загрузка файлов", 'url' => ['#'], 'items' => [ | 285 | ['label' => "Загрузка файлов", 'url' => ['#'], 'items' => [ |
| 286 | + ['label' => 'Кросс-файлы', 'url' => ['crossing-upload/index']], | ||
| 286 | ['label' => 'Файлы на сервере', 'url' => ['parser/server-files']], | 287 | ['label' => 'Файлы на сервере', 'url' => ['parser/server-files']], |
| 287 | ['label' => 'Загрузить файл на сервер', 'url' => ['parser/index', 'mode' => 1]], | 288 | ['label' => 'Загрузить файл на сервер', 'url' => ['parser/index', 'mode' => 1]], |
| 288 | ['label' => 'Ручная загрузка', 'url' => ['parser/index']], | 289 | ['label' => 'Ручная загрузка', 'url' => ['parser/index']], |
common/components/PriceWriter.php
| @@ -65,8 +65,15 @@ class PriceWriter | @@ -65,8 +65,15 @@ class PriceWriter | ||
| 65 | $row['PRICE'] = \Yii::$app->multiparser->convertToFloat($row['PRICE']); | 65 | $row['PRICE'] = \Yii::$app->multiparser->convertToFloat($row['PRICE']); |
| 66 | $row['BOX'] = \Yii::$app->multiparser->convertToInteger($row['BOX']); | 66 | $row['BOX'] = \Yii::$app->multiparser->convertToInteger($row['BOX']); |
| 67 | // присвоим полный артикул | 67 | // присвоим полный артикул |
| 68 | + | ||
| 68 | $row['FULL_ARTICLE'] = $row['ARTICLE']; | 69 | $row['FULL_ARTICLE'] = $row['ARTICLE']; |
| 69 | - $row['ARTICLE'] = \Yii::$app->multiparser->convertToArticle( $row ); | 70 | + if ((int)$this->configuration['delete_prefix']) { |
| 71 | + $row = \Yii::$app->multiparser->convertToArticle( $row, $this->configuration['importer_id'] ); | ||
| 72 | + } else { | ||
| 73 | + $row['ARTICLE'] = \Yii::$app->multiparser->convertToArticle( $row['ARTICLE'] ); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + | ||
| 70 | if (isset($row['ADD_BOX'])) | 77 | if (isset($row['ADD_BOX'])) |
| 71 | $row['ADD_BOX'] = \Yii::$app->multiparser->convertToInteger($row['ADD_BOX']); | 78 | $row['ADD_BOX'] = \Yii::$app->multiparser->convertToInteger($row['ADD_BOX']); |
| 72 | 79 | ||
| @@ -84,9 +91,6 @@ class PriceWriter | @@ -84,9 +91,6 @@ class PriceWriter | ||
| 84 | try { | 91 | try { |
| 85 | //@todo add transaction | 92 | //@todo add transaction |
| 86 | 93 | ||
| 87 | - if ((int)$this->configuration['delete_prefix']) { | ||
| 88 | - $details_model->delete_prefix = true; | ||
| 89 | - } | ||
| 90 | if ((int)$this->configuration['delete_price']) { | 94 | if ((int)$this->configuration['delete_price']) { |
| 91 | $details_model->delete_price = true; | 95 | $details_model->delete_price = true; |
| 92 | } | 96 | } |
common/components/parsers/CustomConverter.php
| @@ -4,6 +4,7 @@ namespace common\components\parsers; | @@ -4,6 +4,7 @@ namespace common\components\parsers; | ||
| 4 | use common\components\CustomVarDamp; | 4 | use common\components\CustomVarDamp; |
| 5 | use yii\multiparser\Converter; | 5 | use yii\multiparser\Converter; |
| 6 | use backend\models\Details; | 6 | use backend\models\Details; |
| 7 | +use backend\models\DetailsCrosses; | ||
| 7 | use backend\models\ImportersPrefix; | 8 | use backend\models\ImportersPrefix; |
| 8 | 9 | ||
| 9 | class CustomConverter extends Converter | 10 | class CustomConverter extends Converter |
| @@ -93,6 +94,22 @@ class CustomConverter extends Converter | @@ -93,6 +94,22 @@ class CustomConverter extends Converter | ||
| 93 | return $row; | 94 | return $row; |
| 94 | } | 95 | } |
| 95 | 96 | ||
| 97 | + public static function convertToCrosses( array $row ) | ||
| 98 | + { | ||
| 99 | + | ||
| 100 | + $details_model = new DetailsCrosses(); | ||
| 101 | + // проверим все ли обязательные колонки были указаны пользователем | ||
| 102 | + $details_model->load(['DetailsCrosses' => $row]); | ||
| 103 | + | ||
| 104 | + if (!$details_model->validate()) { | ||
| 105 | + $errors = ''; | ||
| 106 | + foreach ($details_model->errors as $key => $arr_errors) { | ||
| 107 | + $errors .= "Аттрибут $key - " . implode(' , ', $arr_errors); | ||
| 108 | + } | ||
| 109 | + throw new \ErrorException($errors); | ||
| 110 | + } | ||
| 111 | + return $row; | ||
| 112 | + } | ||
| 96 | public function ConvertToMultiply(array $row) | 113 | public function ConvertToMultiply(array $row) |
| 97 | { | 114 | { |
| 98 | $PRICE = $row['PRICE']; | 115 | $PRICE = $row['PRICE']; |
| @@ -125,31 +142,47 @@ class CustomConverter extends Converter | @@ -125,31 +142,47 @@ class CustomConverter extends Converter | ||
| 125 | 142 | ||
| 126 | } | 143 | } |
| 127 | 144 | ||
| 128 | - public static function convertToArticle( array $row ) | 145 | + public static function convertToArticle( $value, $importer_id = '' ) |
| 129 | { | 146 | { |
| 130 | - if ( isset($row['ARTICLE']) ) { | 147 | + if(isset( $importer_id )){ |
| 148 | + self::$importer_id = $importer_id; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + if (is_array($value)) { | ||
| 131 | 152 | ||
| 153 | + $row = $value; | ||
| 132 | // 1. Уберем префикс который разделен пробелом (если он есть) | 154 | // 1. Уберем префикс который разделен пробелом (если он есть) |
| 133 | $words = explode(" ", $row['ARTICLE']); | 155 | $words = explode(" ", $row['ARTICLE']); |
| 134 | if (count($words) > 1) { | 156 | if (count($words) > 1) { |
| 135 | array_shift($words); | 157 | array_shift($words); |
| 136 | $row['ARTICLE'] = implode(" ", $words); | 158 | $row['ARTICLE'] = implode(" ", $words); |
| 137 | } | 159 | } |
| 138 | - } | ||
| 139 | - if( isset( $row['BRAND'] ) && isset( self::$importer_id ) ){ | ||
| 140 | - // 2. Уберем брендовый префикс (если он есть) | ||
| 141 | - $prefix = ''; | ||
| 142 | - // запрос закешируем | ||
| 143 | - $prefix = ImportersPrefix::getDb()->cache( function ($db, $configuration, $row ) { | ||
| 144 | - return ImportersPrefix::find()->where([ 'importer_id' => self::$importer_id, | ||
| 145 | - 'brand' => $row['BRAND'] ])->one(); | 160 | + |
| 161 | + if( isset( $row['BRAND'] ) && isset( self::$importer_id ) ){ | ||
| 162 | + // 2. Уберем брендовый префикс (если он есть) | ||
| 163 | + $prefix = ''; | ||
| 164 | + // запрос закешируем | ||
| 165 | + $prefix = ImportersPrefix::getDb()->cache( function ($db, $configuration, $row ) { | ||
| 166 | + return ImportersPrefix::find()->where([ 'importer_id' => self::$importer_id, | ||
| 167 | + 'brand' => $row['BRAND'] ])->one(); | ||
| 146 | }); | 168 | }); |
| 147 | 169 | ||
| 148 | - if ($prefix) { | ||
| 149 | - $row['BRAND'] = str_replace($prefix, "", $row['BRAND']); | 170 | + if ($prefix) { |
| 171 | + $row['BRAND'] = str_replace($prefix, "", $row['BRAND']); | ||
| 172 | + } | ||
| 150 | } | 173 | } |
| 174 | + | ||
| 175 | + return $row; | ||
| 176 | + | ||
| 177 | + } else { | ||
| 178 | + $words = explode( " ", $value ); | ||
| 179 | + if ( count( $words ) > 1) { | ||
| 180 | + array_shift( $words ); | ||
| 181 | + $value = implode( " ", $words ); | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + return $value; | ||
| 151 | } | 185 | } |
| 152 | - return $row; | ||
| 153 | } | 186 | } |
| 154 | 187 | ||
| 155 | public static function convertToBrand($value) | 188 | public static function convertToBrand($value) |
common/components/parsers/config.php
| @@ -17,12 +17,11 @@ | @@ -17,12 +17,11 @@ | ||
| 17 | 'hasKey' => 1, | 17 | 'hasKey' => 1, |
| 18 | 'configuration' => ["string" => 'DESCR', | 18 | 'configuration' => ["string" => 'DESCR', |
| 19 | "float" => 'PRICE', | 19 | "float" => 'PRICE', |
| 20 | - "brand" => 'BRAND[', | 20 | + "brand" => 'BRAND', |
| 21 | "integer" => ['BOX','ADD_BOX'], | 21 | "integer" => ['BOX','ADD_BOX'], |
| 22 | "multiply" => [], | 22 | "multiply" => [], |
| 23 | - "details" => [], | ||
| 24 | - "article" => [] | ||
| 25 | - | 23 | + "article" => [], |
| 24 | + "details" => [] | ||
| 26 | ] | 25 | ] |
| 27 | ],], | 26 | ],], |
| 28 | 27 | ||
| @@ -36,6 +35,20 @@ | @@ -36,6 +35,20 @@ | ||
| 36 | "ADD_BOX"=> 'В пути', | 35 | "ADD_BOX"=> 'В пути', |
| 37 | "GROUP" => 'Группа RG' | 36 | "GROUP" => 'Группа RG' |
| 38 | ], | 37 | ], |
| 38 | + | ||
| 39 | + 'crosses' => ['class' => 'common\components\parsers\CustomCsvParser', | ||
| 40 | + 'auto_detect_first_line' => true, | ||
| 41 | + 'min_column_quantity' => 4, | ||
| 42 | + 'hasHeaderRow' => true, | ||
| 43 | + 'keys' =>['ARTICLE', 'CROSS_ARTICLE', 'BRAND', 'CROSS_BRAND'], | ||
| 44 | + 'converter_conf' => [ | ||
| 45 | + //'class' => ' common\components\parsers\CustomConverter', | ||
| 46 | + 'hasKey' => 1, | ||
| 47 | + 'configuration' => [ | ||
| 48 | + "brand" => ['BRAND', 'CROSS_BRAND'], | ||
| 49 | + "crosses" => [], | ||
| 50 | + ] | ||
| 51 | + ],], | ||
| 39 | ], | 52 | ], |
| 40 | 'xml' => | 53 | 'xml' => |
| 41 | ['console' => | 54 | ['console' => |
vendor/yiisoft/multiparser/CsvParser.php
| @@ -59,7 +59,6 @@ class CsvParser implements ParserInterface | @@ -59,7 +59,6 @@ class CsvParser implements ParserInterface | ||
| 59 | */ | 59 | */ |
| 60 | public function setup() | 60 | public function setup() |
| 61 | { | 61 | { |
| 62 | - | ||
| 63 | $this->file->setCsvControl($this->delimiter); | 62 | $this->file->setCsvControl($this->delimiter); |
| 64 | $this->file->setFlags(\SplFileObject::READ_CSV); | 63 | $this->file->setFlags(\SplFileObject::READ_CSV); |
| 65 | $this->file->setFlags(\SplFileObject::SKIP_EMPTY); | 64 | $this->file->setFlags(\SplFileObject::SKIP_EMPTY); |
| @@ -108,7 +107,6 @@ class CsvParser implements ParserInterface | @@ -108,7 +107,6 @@ class CsvParser implements ParserInterface | ||
| 108 | } | 107 | } |
| 109 | 108 | ||
| 110 | for ($i = 1; $i <= count($row); $i++) { | 109 | for ($i = 1; $i <= count($row); $i++) { |
| 111 | - // CustomVarDamp::dump($row[$i]); | ||
| 112 | 110 | ||
| 113 | if ($row[$i - 1] <> '') { | 111 | if ($row[$i - 1] <> '') { |
| 114 | $j++; | 112 | $j++; |
| @@ -179,11 +177,12 @@ class CsvParser implements ParserInterface | @@ -179,11 +177,12 @@ class CsvParser implements ParserInterface | ||
| 179 | protected function readRow( ) | 177 | protected function readRow( ) |
| 180 | { | 178 | { |
| 181 | $row = $this->file->fgetcsv(); | 179 | $row = $this->file->fgetcsv(); |
| 182 | - // уберем нулевые колонки | ||
| 183 | - $row = array_filter($row, function($val){ | ||
| 184 | - return $val <> ''; | ||
| 185 | - }); | 180 | + |
| 186 | if (is_array($row)) { | 181 | if (is_array($row)) { |
| 182 | + // уберем нулевые колонки | ||
| 183 | + $row = array_filter($row, function($val){ | ||
| 184 | + return $val <> ''; | ||
| 185 | + }); | ||
| 187 | // если есть заголовок, то перед конвертацией его нужно назначить | 186 | // если есть заголовок, то перед конвертацией его нужно назначить |
| 188 | if ($this->hasHeaderRow && $this->keys !== NULL) { | 187 | if ($this->hasHeaderRow && $this->keys !== NULL) { |
| 189 | 188 |