ParserController.php
5.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?php
namespace backend\controllers;
use backend\models\UploadFileParsingForm;
use Yii;
use yii\base\ErrorException;
use yii\data\ArrayDataProvider;
use yii\helpers\VarDumper;
use yii\multiparser\DynamicFormHelper;
use yii\web\Controller;
use yii\web\UploadedFile;
/**
* Site controller
*/
class ParserController extends Controller
{
/**
* @var - string
* file parsing extension
*/
protected $file_extension;
public function actionIndex($mode = 0)
{
$model = new UploadFileParsingForm();
return $this->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;
}
}