Commit 7253a9a0d9a9c0dee8591493c006887a508be538
1 parent
118c6c59
Export fix
Showing
5 changed files
with
366 additions
and
117 deletions
Show diff stats
1 | +1. Запускаем миграцию: | |
2 | +php yii migrate --migrationPath=common/modules/comment/migrations | |
3 | +2. Добавляем модуль в конфиг модуль: | |
4 | +'modules' => [ | |
5 | + ... | |
6 | + 'artbox-comment' => [ | |
7 | + 'class' => 'common\modules\comment\Module', | |
8 | + ], | |
9 | +], | |
10 | +3. Добавляем в конфиг переводы: | |
11 | +'i18n' => [ | |
12 | + 'translations' => [ | |
13 | + ... | |
14 | + 'artbox-comment' => [ | |
15 | + 'class' => 'yii\i18n\PhpMessageSource', | |
16 | + 'basePath' => '@common/modules/comment/messages', | |
17 | + ], | |
18 | + ], | |
19 | +], | |
20 | +4. Для управления добавляем в конфиги админки карту контроллера: | |
21 | +'controllerMap' => [ | |
22 | + ... | |
23 | + 'artbox-comments' => [ | |
24 | + 'class' => 'common\modules\comment\controllers\ManageController', | |
25 | + 'viewPath' => '@common/modules/comment/views/manage', | |
26 | + ], | |
27 | +], | |
28 | +5. В конфиге админке поменять пользователя на покупателя: | |
29 | +'modules' => [ | |
30 | + ... | |
31 | + 'artbox-comment' => [ | |
32 | + 'class' => 'common\modules\comment\Module', | |
33 | + 'userIdentityClass' => 'common\models\Customer', | |
34 | + ], | |
35 | +], | |
36 | +6. Вывод виджета: | |
37 | +echo CommentWidget::widget([ | |
38 | + 'model' => $product, | |
39 | +]); | |
40 | +7. Добавляем в нужную модель методы: | |
41 | +public function getComments() { | |
42 | + return $this->hasMany(CommentModel::className(), ['entity_id' => 'product_id'])->where(['artbox_comment.entity' => self::className(), 'artbox_comment.status' => CommentModel::STATUS_ACTIVE, 'artbox_comment.artbox_comment_pid' => NULL]); | |
43 | +} | |
44 | +/** Не обязательно для рейтинга PG ONLY **/ | |
45 | + public function recalculateRating() { | |
46 | + $average = $this->getComments()->joinWith('rating')->select(['average' => 'avg(artbox_comment_rating.value)::float'])->scalar(); | |
47 | + if(!$average) { | |
48 | + $average = 0; | |
49 | + } | |
50 | + $averageRating = $this->averageRating; | |
51 | + if(!empty($averageRating)) { | |
52 | + $averageRating->value = $average; | |
53 | + } else { | |
54 | + $averageRating = new ProductToRating(['product_id' => $this->product_id, 'value' => $average]); // Заменить модель | |
55 | + } | |
56 | + if($averageRating->save()) { | |
57 | + return true; | |
58 | + } else { | |
59 | + return false; | |
60 | + } | |
61 | + } | |
62 | + public function getAverageRating() { | |
63 | + return $this->hasOne(ProductToRating::className(), ['product_id' => 'product_id']); // Заменить модель | |
64 | + } | |
0 | 65 | \ No newline at end of file | ... | ... |
common/modules/product/controllers/ManageController.php
... | ... | @@ -225,13 +225,38 @@ class ManageController extends Controller |
225 | 225 | return $model->goPrices($from, 10); |
226 | 226 | } |
227 | 227 | } |
228 | - | |
229 | - public function actionExport() { | |
228 | + | |
229 | + public function actionExportProcess($from, $filename) | |
230 | + { | |
231 | + | |
230 | 232 | $model = new Export(); |
231 | - if (($file = $model->process(Yii::getAlias('@uploadDir')))) { | |
232 | - return Yii::$app->response->sendFile($file)->send(); | |
233 | + if(Yii::$app->request->isAjax) { | |
234 | + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |
235 | + return $model->process($filename,$from); | |
233 | 236 | } |
234 | - throw new NotFoundHttpException('Error'); | |
237 | + } | |
238 | + | |
239 | + public function actionExport() | |
240 | + { | |
241 | + $model = new Export(); | |
242 | + | |
243 | + if($model->load(Yii::$app->request->post())) { | |
244 | + // PROCESS PAGE | |
245 | + return $this->render('export-process', [ | |
246 | + 'model' => $model, | |
247 | + 'method' => 'export', | |
248 | + ]); | |
249 | + } | |
250 | + | |
251 | + return $this->render('export', [ | |
252 | + 'model' => $model, | |
253 | + ]); | |
254 | + // $model = new Export(); | |
255 | + // if(( $file = $model->process(Yii::getAlias('@uploadDir')) )) { | |
256 | + // return Yii::$app->response->sendFile($file) | |
257 | + // ->send(); | |
258 | + // } | |
259 | + // throw new NotFoundHttpException('Error'); | |
235 | 260 | } |
236 | 261 | |
237 | 262 | /** | ... | ... |
1 | 1 | <?php |
2 | - | |
3 | -namespace common\modules\product\models; | |
4 | - | |
5 | -use common\modules\product\helpers\ProductHelper; | |
6 | -use yii\base\Model; | |
7 | -use yii\helpers\ArrayHelper; | |
8 | - | |
9 | -class Export extends Model { | |
10 | - public $errors = []; | |
11 | - public $output = []; | |
12 | - | |
13 | - public function process($dirName, $filename = null, $use_not_enables = false) { | |
14 | - set_time_limit(0); | |
15 | - ini_set('max_execution_time', 900); | |
16 | - ini_set('memory_limit', '1024M'); | |
17 | - if (is_null($filename)) { | |
18 | - $filename = 'products_'. date('d_m_Y_H_i') .'.csv'; | |
19 | - } | |
20 | - setlocale(LC_ALL, 'ru_RU.CP1251'); | |
21 | - $handle = fopen($dirName .'/'. $filename, "w"); | |
22 | - ///$products = Product::find()->joinWith(['variants'])->where(['!=', ProductVariant::tableName() .'.stock', 0])->select('product.product_id')->all(); | |
23 | - $products = Product::find() | |
24 | - ->joinWith(['variantsWithFilters','brand','categories'])->with('filters')->all(); | |
25 | - | |
26 | - foreach ($products as $product) | |
2 | + | |
3 | + namespace common\modules\product\models; | |
4 | + | |
5 | + use yii\base\Model; | |
6 | + | |
7 | + class Export extends Model | |
8 | + { | |
9 | + | |
10 | + public $lang; | |
11 | + | |
12 | + public $file; | |
13 | + | |
14 | + public $errors = []; | |
15 | + | |
16 | + public $output = []; | |
17 | + | |
18 | + public function process($filename = NULL, $from = 0) | |
27 | 19 | { |
28 | - | |
29 | - | |
30 | - | |
31 | - /*if ($i>1e2) { | |
32 | - break; | |
33 | - }*/ | |
34 | - $mods = []; | |
35 | - | |
36 | - $filterString = $this->convertFilterToString($product->filters); | |
37 | - | |
38 | - foreach ($product->variantsWithFilters as $variant) | |
39 | - { | |
40 | - | |
41 | - $color = $variant->name; | |
42 | - | |
43 | - $mods[] = $variant->sku . | |
44 | - '=' . $this->convertFilterToString($variant->filters) . | |
45 | - '=' . $color . | |
46 | - '=' . ((!empty($variant->image)) ? $variant->image->image: ''). | |
47 | - '=' . $variant->stock; | |
20 | + if(empty( $filename )) { | |
21 | + $filename = 'products_' . date('d_m_Y_H_i') . '.csv'; | |
22 | + $handle = fopen(\Yii::getAlias('@storage/sync/') . $filename, "w"); | |
23 | + } else { | |
24 | + $handle = fopen(\Yii::getAlias('@storage/sync/') . $filename, "a"); | |
25 | + } | |
26 | + | |
27 | + | |
28 | + $products = Product::find() | |
29 | + ->joinWith([ | |
30 | + 'variantsWithFilters', | |
31 | + 'brand', | |
32 | + 'categories', | |
33 | + ]) | |
34 | + ->with('filters') | |
35 | + ->limit(1000) | |
36 | + ->offset($from) | |
37 | + ->all(); | |
38 | + $filesize = Product::find() | |
39 | + ->count(); | |
40 | + foreach($products as $product) { | |
41 | + | |
42 | + $mods = []; | |
43 | + $filterString = $this->convertFilterToString($product->filters); | |
44 | + | |
45 | + foreach($product->variantsWithFilters as $variant) { | |
46 | + $color = $variant->name; | |
47 | + $mods[] = $variant->sku . '=' . $this->convertFilterToString($variant->filters) . '=' . $color . '=' . ( ( !empty( $variant->image ) ) ? $variant->image->image : '' ) . '=' . $variant->stock; | |
48 | + } | |
49 | + | |
50 | + $fotos = []; | |
51 | + | |
52 | + $categories = []; | |
53 | + foreach($product->categories as $value) { | |
54 | + $categories[] = $value->name; | |
55 | + } | |
56 | + | |
57 | + $categories = implode(',', $categories); | |
58 | + | |
59 | + $list = [ | |
60 | + $categories, | |
61 | + $product->brand->name, | |
62 | + $product->name, | |
63 | + '', | |
64 | + ( ( !empty( $product->description ) ) ? $product->description : '' ), | |
65 | + $filterString, | |
66 | + ( !empty( $product->variant ) ) ? $product->variant->price_old : '', | |
67 | + ( !empty( $product->variant ) ) ? $product->variant->price : '', | |
68 | + intval($product->akciya), | |
69 | + '', | |
70 | + intval($product->is_new), | |
71 | + intval($product->is_top), | |
72 | + $product->video, | |
73 | + implode(',', $fotos), | |
74 | + ]; | |
75 | + $to_write = array_merge($list, $mods); | |
76 | + fputcsv($handle, $to_write, ';'); | |
77 | + unset( $product ); | |
48 | 78 | } |
49 | - | |
50 | - | |
51 | - $fotos = []; | |
52 | - | |
53 | -// foreach ($product->images as $image) | |
54 | -// { | |
55 | -// $fotos[] = $image->imageUrl; | |
56 | -// } | |
57 | - | |
58 | -// $filters = $product->properties; | |
59 | - $categories = []; | |
60 | - foreach($product->categories as $value){ | |
61 | - | |
62 | - $categories[] = $value->name; | |
63 | - | |
79 | + | |
80 | + fclose($handle); | |
81 | + | |
82 | + $from += 1000; | |
83 | + $end = false; | |
84 | + if($from > $filesize) { | |
85 | + $end = true; | |
64 | 86 | } |
65 | - | |
66 | - | |
67 | - $categories = implode(',',$categories); | |
68 | - | |
69 | - $list = [ | |
70 | - | |
71 | - $categories, | |
72 | - $product->brand->name, | |
73 | - $product->name, | |
74 | - '', | |
75 | - ((! empty($product->description)) ? $product->description : ''), | |
76 | - $filterString, | |
77 | - (!empty($product->variant)) ? $product->variant->price_old : '', | |
78 | - (!empty($product->variant)) ? $product->variant->price : '', | |
79 | - intval($product->akciya), | |
80 | - '', | |
81 | - intval($product->is_new), | |
82 | - intval($product->is_top), | |
83 | - $product->video, | |
84 | - implode (',', $fotos), | |
87 | + | |
88 | + $result = [ | |
89 | + 'end' => $end, | |
90 | + 'from' => $from, | |
91 | + 'totalsize' => $filesize, | |
92 | + 'filename' => $filename, | |
85 | 93 | ]; |
86 | - | |
87 | - $to_write = array_merge ($list, $mods); | |
88 | - foreach($to_write as &$cell) { | |
89 | - $cell = iconv("UTF-8", "WINDOWS-1251", $cell); | |
94 | + | |
95 | + if($end) { | |
96 | + $result = array_merge($result, [ | |
97 | + 'link' => '/storage/sync/'.$filename, | |
98 | + ]); | |
90 | 99 | } |
91 | - | |
92 | - | |
93 | - fputcsv($handle, $to_write, ';'); | |
94 | - unset($product); | |
95 | - | |
96 | - } | |
97 | - | |
98 | - | |
99 | - | |
100 | - fclose ($handle); | |
101 | - | |
102 | - return $dirName .'/'. $filename; | |
103 | - } | |
104 | - | |
105 | - | |
106 | - public function convertFilterToString($filters){ | |
107 | - $fittersArray = []; | |
108 | - foreach($filters as $filter){ | |
109 | - $fittersArray[$filter->taxGroup->alias][] = $filter->name; | |
100 | + | |
101 | + return $result; | |
102 | + | |
110 | 103 | } |
111 | - $filterString=[]; | |
112 | - | |
113 | - foreach($fittersArray as $filterName =>$filterRows ){ | |
114 | - $row = implode(',',$filterRows); | |
115 | - $filterString[] = "[{$filterName}:{$row}]"; | |
116 | - | |
104 | + | |
105 | + public function convertFilterToString($filters) | |
106 | + { | |
107 | + $fittersArray = []; | |
108 | + foreach($filters as $filter) { | |
109 | + $fittersArray[ $filter->taxGroup->alias ][] = $filter->value; | |
110 | + } | |
111 | + $filterString = []; | |
112 | + | |
113 | + foreach($fittersArray as $filterName => $filterRows) { | |
114 | + $row = implode(',', $filterRows); | |
115 | + $filterString[] = "[{$filterName}:{$row}]"; | |
116 | + } | |
117 | + return implode('*', $filterString); | |
117 | 118 | } |
118 | - return implode('*',$filterString); | |
119 | - } | |
120 | -} | |
121 | 119 | \ No newline at end of file |
120 | + } | |
122 | 121 | \ No newline at end of file | ... | ... |
common/modules/product/views/manage/export-process.php
0 → 100644
1 | +<?php | |
2 | + /** | |
3 | + * @var View $this | |
4 | + */ | |
5 | + | |
6 | +use yii\helpers\Html; | |
7 | + use yii\web\View; | |
8 | + use yii\widgets\ActiveForm; | |
9 | + | |
10 | +?> | |
11 | +<?php | |
12 | +$this->registerJs("var in_process=true; | |
13 | + var count=1; | |
14 | + var filename = null; | |
15 | + | |
16 | + doExport(0,filename); | |
17 | + | |
18 | + function doExport(from,filename) { | |
19 | + from = typeof(from) != 'undefined' ? from : 0; | |
20 | + | |
21 | + $.ajax({ | |
22 | + method: 'get', | |
23 | + url: '".Yii::$app->request->baseUrl .'/product/manage/export-process'."', | |
24 | + data: { | |
25 | + from:from, | |
26 | + filename: filename | |
27 | + }, | |
28 | + dataType: 'json', | |
29 | + success: function(data){ | |
30 | + | |
31 | + var per = Math.round(100*data.from/data.totalsize)+'%'; | |
32 | + $('#progressbar div').css({width: per}); | |
33 | + | |
34 | + if(data != false && !data.end) | |
35 | + { | |
36 | + doExport(data.from,data.filename); | |
37 | + } | |
38 | + else | |
39 | + { | |
40 | + console.log(data.link); | |
41 | + $(progressbar).hide('fast'); | |
42 | + $('#result_link').attr('href', data.link).removeClass('hidden'); | |
43 | + in_process = false; | |
44 | + } | |
45 | + }, | |
46 | + error: function(xhr, status, errorThrown) { | |
47 | + } | |
48 | + }); | |
49 | + }"); | |
50 | +?> | |
51 | + | |
52 | +<!--<script>--> | |
53 | +<!-- var in_process=true;--> | |
54 | +<!-- var count=1;--> | |
55 | +<!-- var filename = null;--> | |
56 | +<!-- --> | |
57 | +<!-- doExport(0,filename);--> | |
58 | +<!-- --> | |
59 | +<!-- function doExport(from,filename) {--> | |
60 | +<!-- from = typeof(from) != 'undefined' ? from : 0;--> | |
61 | +<!-- --> | |
62 | +<!-- $.ajax({--> | |
63 | +<!-- method: 'get',--> | |
64 | +<!-- url: '".Yii::$app->request->baseUrl .'/product/manage/export-process'."',--> | |
65 | +<!-- data: {--> | |
66 | +<!-- from:from,--> | |
67 | +<!-- filename: filename--> | |
68 | +<!-- },--> | |
69 | +<!-- dataType: 'json',--> | |
70 | +<!-- success: function(data){--> | |
71 | +<!-- --> | |
72 | +<!-- var per = Math.round(100*data.from/data.totalsize)+'%';--> | |
73 | +<!-- $('#progressbar div').css({width: per});--> | |
74 | +<!-- --> | |
75 | +<!-- if(data != false && !data.end)--> | |
76 | +<!-- {--> | |
77 | +<!-- doExport(data.from,data.filename);--> | |
78 | +<!-- }--> | |
79 | +<!-- else--> | |
80 | +<!-- {--> | |
81 | +<!-- console.log(data.link);--> | |
82 | +<!-- progressbar.hide('fast');--> | |
83 | +<!-- in_process = false;--> | |
84 | +<!-- }--> | |
85 | +<!-- },--> | |
86 | +<!-- error: function(xhr, status, errorThrown) {--> | |
87 | +<!-- }--> | |
88 | +<!-- });--> | |
89 | +<!-- }--> | |
90 | +<!--</script>--> | |
91 | + | |
92 | +<div class="product-import-process-form"> | |
93 | + <h1>Экспорт данных товаров</h1> | |
94 | + | |
95 | + <?= \yii\jui\ProgressBar::widget([ | |
96 | + 'clientOptions' => [ | |
97 | + 'value' => 100, | |
98 | + 'label' => '' | |
99 | + ], | |
100 | + 'options' => [ | |
101 | + 'id' => 'progressbar' | |
102 | + ], | |
103 | + ]);?> | |
104 | + <ul id="process-result"></ul> | |
105 | + <a id="result_link" href="" class="hidden">Ссылка на файл!</a> | |
106 | +</div> | ... | ... |
1 | +<?php | |
2 | + | |
3 | + use yii\helpers\Html; | |
4 | + use yii\widgets\ActiveForm; | |
5 | + | |
6 | +?> | |
7 | + | |
8 | +<div class="product-import-form"> | |
9 | + <?php $form = ActiveForm::begin([ | |
10 | + 'enableClientValidation' => false, | |
11 | + 'options' => [ 'enctype' => 'multipart/form-data' ], | |
12 | + ]); ?> | |
13 | + | |
14 | + <?php if($model->errors) : ?> | |
15 | + <div class="error"> | |
16 | + <?= implode("<br>\n", $model->errors); ?> | |
17 | + </div> | |
18 | + <?php endif ?> | |
19 | + | |
20 | + <?php if($model->output) : ?> | |
21 | + <h2>Лог операции</h2> | |
22 | + <div class="success" style="height: 10em;overflow: auto;border: 1px solid #000"> | |
23 | + <?= implode("<br>\n", $model->output); ?> | |
24 | + </div> | |
25 | + <?php endif ?> | |
26 | + | |
27 | + <?= $form->field($model, 'lang') | |
28 | + ->hiddenInput([ | |
29 | + 'options' => [ | |
30 | + 'value' => 1, | |
31 | + ], | |
32 | + ])->label(false); ?> | |
33 | + | |
34 | + | |
35 | + | |
36 | + | |
37 | + <?php /*= $form->field($model, 'file')->widget(\kartik\file\FileInput::classname(), [ | |
38 | + 'language' => 'ru', | |
39 | + 'options' => [ | |
40 | + 'multiple' => false, | |
41 | + ], | |
42 | + 'pluginOptions' => [ | |
43 | + 'allowedFileExtensions' => ['csv'], | |
44 | + 'overwriteInitial' => true, | |
45 | + 'showRemove' => false, | |
46 | + 'showUpload' => false, | |
47 | + ], | |
48 | + ])*/ ?> | |
49 | + | |
50 | + <div class="form-group"> | |
51 | + <?= Html::submitButton(Yii::t('product', 'Export'), [ 'class' => 'btn btn-primary' ]) ?> | |
52 | + </div> | |
53 | + | |
54 | + <?php ActiveForm::end(); ?> | |
55 | +</div> | |
0 | 56 | \ No newline at end of file | ... | ... |