diff --git a/examples/ParserController.php b/examples/ParserController.php new file mode 100644 index 0000000..5a2114d --- /dev/null +++ b/examples/ParserController.php @@ -0,0 +1,156 @@ +render('index', ['model' => $model]); + } + + public function actionRead() + { + $model = new UploadFileParsingForm(); + $data = []; + $mode = ''; + if ($model->load(\Yii::$app->request->post())) { + if (!$model->file_type) { + $model->file = UploadedFile::getInstance($model, 'file'); + } + if ($model->validate()) { + // get the extension of user chosen file + $this->file_extension = $this->getFileExtensionFromModel($model); + + if ($model->file_type) { + $model->file_path = dirname(dirname(__DIR__)) . '/tests/_data/template.' . $this->file_extension; + $mode = 'template'; + } else { + $mode = 'custom'; + $model->file_path = dirname(dirname(__DIR__)) . '/tests/_data/custom_template.' . $this->file_extension; + $model->file->saveAs($model->file_path); + } + + // run parsing + $data = $model->readFile(['mode' => $mode]); + + if ($mode == 'custom' && file_exists($model->file_path)) { + unlink($model->file_path); + } + // safe parse data to cache + Yii::$app->getCache()->set('parser_data', json_encode($data), 300); + + } else { + // handle with error validation form + $errors_str = 'Error upload form'; + foreach ($model->getErrors() as $error) { + $errors_str .= ' ' . implode(array_values($error)); + } + + throw new ErrorException($errors_str); + } + + } elseif (Yii::$app->getCache()->get('parser_data')) { + // it's a get request, so retrive data from cache + $data = json_decode(Yii::$app->getCache()->get('parser_data'), true); + } + + return $this->renderResultView($data, $mode); + } + + public function getFileExtensionFromModel($model) + { + switch ($model->file_type) { + case 0: + return $model->file->extension; + case 1: + return 'csv'; + case 2: + return 'xml'; + case 3: + return 'xlsx'; + default: + return 'csv'; + } + + } + + public function renderResultView($data ) + { + $provider = new ArrayDataProvider([ + 'allModels' => $data, + 'pagination' => [ + 'pageSize' => 10, + ], + ]); + // если отпарсенные данные - ассоциативный массив, то пользователю нечего выбирать + $assoc_data_arr = $this->is_assoc($data[0]); + + if ( $assoc_data_arr ) { + + // $mode == 'template' or xml file + // парсинг с файла по шаблону + // согласно конфигурационного файла у нас колонкам назначены ключи + // то есть результат - ассоциативный массив, у пользователя нечего спрашивать + // данные отконвертированы согласно настройкам и готовы к записи в БД (или к дальнейшей обработке) + + return $this->render('results', + ['model' => $data, + // список колонок для выбора + 'dataProvider' => $provider]); + + } else { + // $mode == 'custom' and not xml + // для произвольного файла создадим страницу предпросмотра + // с возможностью выбора соответсвий колонок с отпарсенными данными + //колонки для выбора возьмем из конфигурационного файла - опция - 'basic_column' + + // создадим динамическую модель на столько реквизитов сколько колонок в отпарсенном файле + // в ней пользователь произведет свой выбор + $last_index = end(array_flip($data[0])); + $header_counts = $last_index + 1; // - количество колонок выбора формы предпросмотра + $header_model = DynamicFormHelper::CreateDynamicModel($header_counts); + + // колонки для выбора возьмем из конфигурационного файла + $basicColumns = Yii::$app->multiparser->getConfiguration($this->file_extension, 'basic_column');; + + return $this->render('results', + ['model' => $data, + 'header_model' => $header_model, + // список колонок для выбора + 'basic_column' => $basicColumns, + 'dataProvider' => $provider]); + } + + } + + private function is_assoc(array $array) + { + // Keys of the array + $keys = array_keys($array); + + // If the array keys of the keys match the keys, then the array must + // not be associative (e.g. the keys array looked like {0:0, 1:1...}). + return array_keys($keys) !== $keys; + } + +} diff --git a/examples/UploadFileParsingForm.php b/examples/UploadFileParsingForm.php new file mode 100644 index 0000000..77def70 --- /dev/null +++ b/examples/UploadFileParsingForm.php @@ -0,0 +1,71 @@ + range( 0, 3 ) ], + ['file', 'required', 'when' => function(){ + return !$this->file_type; + } , 'whenClient' => $client_func], + [['file'], 'file', 'extensions' => ['csv', 'xlsx', 'xml'], 'checkExtensionByMimeType' => false ], + ['file_path', 'safe'], + + ]; + } + + public function attributeLabels() + { + return [ + 'file' => Yii::t('app', 'Custom file'), + ]; + } + + public function readFile( $options = [] ){ + + $data = Yii::$app->multiparser->parse( $this->file_path, $options ); + + if( !is_array( $data ) || count($data) == 0 ){ + throw new ErrorException("Reading error from file - {$this->file_path}"); + } + + if( !$this->file_path && file_exists( $this->file_path ) ) + unlink( $this->file_path ); + + return $data; + } + + + + +} \ No newline at end of file diff --git a/examples/config.php b/examples/config.php new file mode 100644 index 0000000..a8e0bff --- /dev/null +++ b/examples/config.php @@ -0,0 +1,98 @@ + + ['custom' => + ['class' => 'yii\multiparser\CsvParser', + 'converter_conf' => [ + 'class' => 'yii\multiparser\Converter', + 'configuration' => ["encode" => []], + ] + ], + 'template' => + ['class' => 'yii\multiparser\CsvParser', + 'keys' => [ + 0 => 'Description', + 1 => 'Article', + 2 => 'Price', + 3 => 'Brand', + 4 => 'Count', + ], + 'converter_conf' => [ + 'class' => 'yii\multiparser\Converter', + 'configuration' => ["encode" => 'Description', + "string" => ['Description', 'Brand'], + "float" => 'Price', + "integer" => 'Count' + ] + ],], + + 'basic_column' => [ + Null => 'null', + "Description" => 'Название', + "Article" => 'Артикул', + "Price" => 'Цена', + "Brand" => 'Производитель', + "Count" => 'Количество', + ], + ], + 'xml' => + ['custom' => + ['class' => 'yii\multiparser\XmlParser', + 'converter_conf' => [ + 'class' => 'yii\multiparser\Converter', + 'configuration' => ["encode" => []], + ] + ], + 'template' => + ['class' => 'yii\multiparser\XmlParser', + 'node' => 'Товар', + 'has_header_row' => false, + 'keys' => [ + "BRAND" => 'Производитель', + "ARTICLE" => 'Код', + "PRICE" => 'Розница', + "DESCR" => 'Наименование', + "BOX" => 'Колво', + "ADD_BOX" => 'Ожидаемое', + "GROUP" => 'Группа' + ], + 'converter_conf' => [ + 'class' => 'yii\multiparser\Converter', + 'configuration' => [ + 'converter_conf' => [ + 'class' => 'yii\multiparser\Converter', + 'configuration' => ["encode" => 'DESCR', + "string" => ['DESCR', 'BRAND'], + "float" => 'PRICE', + "integer" => ['BOX', 'ADD_BOX'], + ], + ], + ], + ], + ], + 'basic_column' => [ + Null => 'null', + "BRAND" => 'Производитель', + "ARTICLE" => 'Код', + "PRICE" => 'Розница', + "DESCR" => 'Наименование', + "BOX" => 'Колво', + "ADD_BOX" => 'Ожидаемое', + "GROUP" => 'Группа' + ], + ], + 'xlsx' => + ['web' => + ['class' => 'common\components\parsers\XlsxParser', + // 'path_for_extract_files' => \Yii::getAlias('@temp_upload') . '/xlsx/', + //'auto_detect_first_line' => true, + //'has_header_row' => true, + 'active_sheet' => 1, + 'converter_conf' => [ + 'class' => 'common\components\parsers\CustomConverter', + 'configuration' => ["string" => []], + ] + ], + ] +]; + diff --git a/examples/parser/index.php b/examples/parser/index.php new file mode 100644 index 0000000..9a0d2e1 --- /dev/null +++ b/examples/parser/index.php @@ -0,0 +1,26 @@ + +
+
+ ['enctype' => 'multipart/form-data',],'action'=>['parser/read']]); + ?> +

Choose file to parse

+ + field($model, 'file')->fileInput() ?> + + field($model, 'file_type')->radioList([0 => 'Custom file', 1 => 'csv template', 2 => 'xml template', 3 => 'xlsx template'])->label(false); + ?> + +
+ 'btn btn-primary']) ?> +
+ + +
+
+ diff --git a/examples/parser/results.php b/examples/parser/results.php new file mode 100644 index 0000000..9eb650f --- /dev/null +++ b/examples/parser/results.php @@ -0,0 +1,38 @@ +title = 'Results'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ 'write']); + + if (empty( $header_model )) { + // выведем просто массив без колонок выбора + echo \yii\grid\GridView::widget([ + 'dataProvider' => $dataProvider, + // 'layout'=>"{pager}\n{items}", + + ]); + + } else { + echo DynamicFormHelper::CreateGridWithDropDownListHeader($dataProvider, $form, $header_model, $basic_column); + } + ?> + + + 'btn btn-primary', 'name' => 'Return',]) ?> + +
\ No newline at end of file -- libgit2 0.21.4