Completed
Push — master ( 56b3e0...fb6bd6 )
by Dmitry
04:00
created

ServerGridView.php$0 ➔ getTypeOfSale()   B

Complexity

Conditions 5

Size

Total Lines 59

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 59
ccs 0
cts 50
cp 0
rs 8.5833
c 0
b 0
f 0
cc 5
crap 30

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Server module for HiPanel
4
 *
5
 * @link      https://github.com/hiqdev/hipanel-module-server
6
 * @package   hipanel-module-server
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2018, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\modules\server\grid;
12
13
use hipanel\base\Model;
14
use hipanel\grid\MainColumn;
15
use hipanel\grid\RefColumn;
16
use hipanel\grid\XEditableColumn;
17
use hipanel\helpers\Url;
18
use hipanel\modules\hosting\controllers\AccountController;
0 ignored issues
show
Bug introduced by SilverFire - Dmitry Naumenko
The type hipanel\modules\hosting\...llers\AccountController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use hipanel\modules\hosting\controllers\IpController;
0 ignored issues
show
Bug introduced by SilverFire - Dmitry Naumenko
The type hipanel\modules\hosting\controllers\IpController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use hipanel\modules\server\menus\ServerActionsMenu;
21
use hipanel\modules\server\models\Consumption;
22
use hipanel\modules\server\widgets\DiscountFormatter;
23
use hipanel\modules\server\widgets\Expires;
24
use hipanel\modules\server\widgets\OSFormatter;
25
use hipanel\modules\server\widgets\ResourceConsumptionTable;
26
use hipanel\modules\server\widgets\State;
27
use hipanel\widgets\ArraySpoiler;
28
use hipanel\widgets\gridLegend\ColorizeGrid;
29
use hipanel\widgets\gridLegend\GridLegend;
30
use hipanel\widgets\Label;
31
use hiqdev\yii2\menus\grid\MenuColumn;
32
use Tuck\Sort\Sort;
33
use Yii;
34
use yii\data\ArrayDataProvider;
35
use yii\helpers\ArrayHelper;
36
use yii\helpers\Html;
37
38
class ServerGridView extends \hipanel\grid\BoxedGridView
39
{
40
    use ColorizeGrid;
0 ignored issues
show
introduced by tofid
The trait hipanel\widgets\gridLegend\ColorizeGrid requires some properties which are not provided by hipanel\modules\server\grid\ServerGridView: $controller, $module
Loading history...
41
42
    public $controllerUrl = '@server';
43
44
    /**
45
     * @var array
46
     */
47
    public $osImages;
48
49
    protected function formatTariff($model)
50
    {
51
        if (Yii::$app->user->can('plan.read')) {
0 ignored issues
show
Bug introduced by Yurii Myronchuk
The method can() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

51
        if (Yii::$app->user->/** @scrutinizer ignore-call */ can('plan.read')) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
52
            if ($model->parent_tariff) {
53
                $title = Html::tag('abbr', $model->parent_tariff, [
54
                    'title' => $model->tariff, 'data-toggle' => 'tooltip',
55
                ]);
56
            } else {
57
                $title = $model->tariff;
58
            }
59
60
            return Html::a($title, ['@plan/view', 'id' => $model->tariff_id]);
61
        }
62
63
        return !empty($model->parent_tariff) ? $model->parent_tariff : $model->tariff;
64
    }
65
66
    public function columns()
67
    {
68
        $canAdmin = Yii::$app->user->can('admin');
0 ignored issues
show
Unused Code introduced by SilverFire - Dmitry Naumenko
The assignment to $canAdmin is dead and can be removed.
Loading history...
69
        $canSupport = Yii::$app->user->can('support');
70
71
        return array_merge(parent::columns(), [
72
            'server' => [
73
                'class' => MainColumn::class,
74
                'attribute' => 'name',
75
                'filterAttribute' => 'name_like',
76
                'note' => Yii::$app->user->can('server.set-label') ? 'label' : 'note',
77
                'noteOptions' => [
78
                    'url' => Yii::$app->user->can('server.set-label') ? Url::to('set-label') : (Yii::$app->user->can('server.set-note') ? Url::to('set-note') : ''),
79
                ],
80
                'badges' => function ($model) use ($canSupport) {
81
                    $badges = '';
82
                    if ($canSupport) {
83
                        if ($model->wizzarded) {
84
                            $badges .= Label::widget(['label' => 'W', 'tag' => 'sup', 'color' => 'success']);
85
                        }
86
                    }
87
88
                    return $badges;
89
                },
90
            ],
91
            'dc' => [
92
                'attribute' => 'dc',
93
                'filter' => false,
94
            ],
95
            'state' => [
96
                'class' => RefColumn::class,
97
                'filterOptions' => ['class' => 'narrow-filter'],
98
                'i18nDictionary' => 'hipanel:server',
99
                'format' => 'raw',
100
                'gtype' => 'state,device',
101
                'value' => function ($model) {
102
                    $html = State::widget(compact('model'));
103
                    if ($model->status_time) {
104
                        $html .= ' ' . Html::tag('nobr', Yii::t('hipanel:server', 'since {date}', ['date' => Yii::$app->formatter->asDate($model->status_time)]));
105
                    }
106
107
                    return $html;
108
                },
109
            ],
110
            'panel' => [
111
                'attribute' => 'panel',
112
                'format' => 'html',
113
                'contentOptions' => ['class' => 'text-uppercase'],
114
                'value' => function ($model) use ($canSupport) {
115
                    $value = $model->getPanel() ? Yii::t('hipanel:server:panel', $model->getPanel()) : Yii::t('hipanel:server:panel', 'No control panel');
116
                    if ($canSupport) {
117
                        $value .= $model->wizzarded ? Label::widget([
118
                            'label' => 'W', 'tag' => 'sup', 'color' => 'success',
119
                        ]) : '';
120
                    }
121
122
                    return $value;
123
                },
124
            ],
125
            'os' => [
126
                'attribute' => 'os',
127
                'format' => 'raw',
128
                'value' => function ($model) {
129
                    return OSFormatter::widget([
130
                        'osimages' => $this->osImages,
131
                        'imageName' => $model->osimage,
132
                    ]);
133
                },
134
            ],
135
            'os_and_panel' => [
136
                'attribute' => 'os',
137
                'format' => 'raw',
138
                'value' => function ($model) {
139
                    $html = OSFormatter::widget([
140
                        'osimages' => $this->osImages,
141
                        'imageName' => $model->osimage,
142
                    ]);
143
                    $html .= ' ' . ($model->panel ?: '');
144
145
                    return $html;
146
                },
147
            ],
148
            'discount' => [
149
                'attribute' => 'discount',
150
                'label' => Yii::t('hipanel:server', 'Discount'),
151
                'format' => 'raw',
152
                'headerOptions' => ['style' => 'width: 1em'],
153
                'value' => function ($model) {
154
                    return DiscountFormatter::widget([
155
                        'current' => $model->discounts['fee']['current'],
156
                        'next' => $model->discounts['fee']['next'],
157
                    ]);
158
                },
159
            ],
160
            'expires' => [
161
                'filter' => false,
162
                'format' => 'raw',
163
                'headerOptions' => ['style' => 'width: 1em'],
164
                'value' => function ($model) {
165
                    return Expires::widget(compact('model'));
166
                },
167
            ],
168
            'tariff' => [
169
                'format' => 'raw',
170
                'filterAttribute' => 'tariff_like',
171
                'value' => function ($model) {
172
                    return $this->formatTariff($model);
173
                },
174
            ],
175
            'tariff_and_discount' => [
176
                'attribute' => 'tariff',
177
                'filterAttribute' => 'tariff_like',
178
                'format' => 'raw',
179
                'value' => function ($model) {
180
                    return $this->formatTariff($model) . ' ' . DiscountFormatter::widget([
181
                            'current' => $model->discounts['fee']['current'],
182
                            'next' => $model->discounts['fee']['next'],
183
                        ]);
184
                },
185
            ],
186
            'ip' => [
187
                'filter' => false,
188
            ],
189
            'mac' => [
190
                'filter' => false,
191
            ],
192
            'ips' => [
193
                'format' => 'raw',
194
                'attribute' => 'ips',
195
                'filter' => false,
196
                'value' => function ($model) {
197
                    return ArraySpoiler::widget([
198
                        'data' => ArrayHelper::getColumn($model->ips, 'ip'),
199
                        'delimiter' => '<br />',
200
                        'visibleCount' => 3,
201
                        'button' => ['popoverOptions' => ['html' => true]],
202
                    ]);
203
                },
204
            ],
205
            'sale_time' => [
206
                'attribute' => 'sale_time',
207
                'format' => 'datetime',
208
            ],
209
            'note' => [
210
                'class' => XEditableColumn::class,
211
                'pluginOptions' => [
212
                    'url' => Url::to('set-note'),
213
                ],
214
                'widgetOptions' => [
215
                    'linkOptions' => [
216
                        'data-type' => 'textarea',
217
                    ],
218
                ],
219
                'visible' => Yii::$app->user->can('server.set-note'),
220
            ],
221
            'label' => [
222
                'class' => XEditableColumn::class,
223
                'pluginOptions' => [
224
                    'url' => Url::to('set-label'),
225
                ],
226
                'widgetOptions' => [
227
                    'linkOptions' => [
228
                        'data-type' => 'textarea',
229
                    ],
230
                ],
231
                'visible' => Yii::$app->user->can('server.set-label'),
232
            ],
233
            'type' => [
234
                'format' => 'html',
235
                'filter' => false,
236
                'value' => function ($model) {
237
                    return Html::tag('span', $model->type_label, ['class' => 'label label-default']);
238
                },
239
            ],
240
            'detailed_type' => [
241
                'label' => Yii::t('hipanel', 'Type'),
242
                'format' => 'html',
243
                'filter' => false,
244
                'value' => function ($model) {
245
                    return Html::tag('span', $model->type_label, ['class' => 'label label-default']);
246
                },
247
                'contentOptions' => function ($model) {
248
                    return GridLegend::create($this->findOrFailGridLegend($model))->gridColumnOptions('actions');
249
                },
250
            ],
251
            'rack' => [
252
                'class' => BindingColumn::class,
253
            ],
254
            'net' => [
255
                'class' => BindingColumn::class,
256
            ],
257
            'kvm' => [
258
                'class' => BindingColumn::class,
259
            ],
260
            'pdu' => [
261
                'class' => BindingColumn::class,
262
            ],
263
            'ipmi' => [
264
                'class' => BindingColumn::class,
265
            ],
266
            'nums' => [
267
                'label' => '',
268
                'format' => 'raw',
269
                'value' => function ($model) {
270
                    $ips_num = $model->ips_num;
271
                    $ips = $ips_num ? Html::a("$ips_num ips", IpController::getSearchUrl(['server' => $model->name])) : 'no ips';
272
                    $act_acs_num = $model->acs_num - $model->del_acs_num;
273
                    $del_acs_num = $model->del_acs_num;
274
                    $acs_num = $act_acs_num . ($del_acs_num ? "+$del_acs_num" : '');
275
                    $acs = $acs_num ? Html::a("$acs_num acc", AccountController::getSearchUrl(['server' => $model->name])) : 'no acc';
276
277
                    return Html::tag('nobr', $ips) . ' ' . Html::tag('nobr', $acs);
278
                },
279
            ],
280
            'monthly_fee' => [
281
                'label' => Yii::t('hipanel:finance', 'Monthly fee'),
282
                'format' => 'html',
283
                'filter' => false,
284
                'value' => function ($model) {
285
                    return isset($model->consumptions['monthly,monthly']) ? $this->getFormattedConsumptionFor($model->consumptions['monthly,monthly']) : null;
286
                },
287
                'visible' => Yii::$app->user->can('consumption.read'),
288
            ],
289
            'traffic' => [
290
                'label' => Yii::t('hipanel:server', 'Traffic'),
291
                'format' => 'html',
292
                'filter' => false,
293
                'value' => function ($model) {
294
                    return isset($model->consumptions['overuse,server_traf_max']) ? $this->getFormattedConsumptionFor($model->consumptions['overuse,server_traf_max']) : null;
295
                },
296
                'visible' => Yii::$app->user->can('consumption.read'),
297
            ],
298
            'additional_services' => [
299
                'label' => Yii::t('hipanel:server', 'Additional services'),
300
                'format' => 'raw',
301
                'filter' => false,
302
                'contentOptions' => ['class' => 'no-padding'],
303
                'value' => function ($model) {
304
                    return $this->getAdditionalServices($model);
305
                },
306
                'visible' => Yii::$app->user->can('consumption.read'),
307
            ],
308
            'type_of_sale' => [
309
                'label' => Yii::t('hipanel:server', 'Type of sale'),
310
                'format' => 'raw',
311
                'filter' => false,
312
                'value' => function ($model) {
313
                    return $this->getTypeOfSale($model);
314
                },
315
                'visible' => Yii::$app->user->can('consumption.read'),
316
            ],
317
            'actions' => [
318
                'class' => MenuColumn::class,
319
                'menuClass' => ServerActionsMenu::class,
320
                'contentOptions' => [
321
                    'class' => 'text-center',
322
                    'style' => 'width:1%; white-space:nowrap;',
323
                ],
324
            ],
325
        ]);
326
    }
327
328
    private function getFormattedConsumptionFor(Consumption $consumption): string
329
    {
330
        $result = '';
331
        $widget = Yii::createObject(['class' => ResourceConsumptionTable::class, 'model' => $consumption]);
332
333
        if ($limit = $widget->getFormatted($consumption, $consumption->limit)) {
0 ignored issues
show
Bug Best Practice introduced by Andrey Klochok
The property limit does not exist on hipanel\modules\server\models\Consumption. Since you implemented __get, consider adding a @property annotation.
Loading history...
334
            $result .= sprintf('%s: %s<br />',
335
                Html::tag('b', Yii::t('hipanel:server', 'included')),
336
                $limit
337
            );
338
        }
339
        if ($price = Yii::$app->formatter->asCurrency($consumption->price, $consumption->currency)) {
0 ignored issues
show
Bug Best Practice introduced by Andrey Klochok
The property currency does not exist on hipanel\modules\server\models\Consumption. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by Andrey Klochok
The property price does not exist on hipanel\modules\server\models\Consumption. Since you implemented __get, consider adding a @property annotation.
Loading history...
340
            $result .= sprintf('%s: %s',
341
                Html::tag('b', Yii::t('hipanel:server', 'price')),
342
                $price
343
            );
344
        }
345
346
        return $result;
347
    }
348
349
    private function getAdditionalServices($model): string
350
    {
351
        $additional = new class() extends Model
352
        {
353
            /**
354
             * @var string
355
             */
356
            public $typeLabel;
357
358
            /**
359
             * @var string
360
             */
361
            public $value;
362
        };
363
        $models = [];
364
        if (isset($model->consumptions['overuse,support_time'])) {
365
            $support = $model->consumptions['overuse,support_time'];
366
            $models[] = new $additional([
367
                'typeLabel' => Yii::t('hipanel.server.consumption.type', $support->typeLabel),
368
                'value' => $this->getFormattedConsumptionFor($support),
369
            ]);
370
        }
371
        if (isset($model->consumptions['overuse,backup_du'])) {
372
            $backup = $model->consumptions['overuse,backup_du'];
373
            $models[] = new $additional([
374
                'typeLabel' => Yii::t('hipanel.server.consumption.type', $backup->typeLabel),
375
                'value' => $this->getFormattedConsumptionFor($backup),
376
            ]);
377
        }
378
        if (isset($model->consumptions['monthly,win_license'])) {
379
            $win_license = $model->consumptions['monthly,win_license'];
380
            $models[] = new $additional([
381
                'typeLabel' => Yii::t('hipanel.server.consumption.type', $win_license->typeLabel),
382
                'value' => $this->getFormattedConsumptionFor($win_license),
383
            ]);
384
        }
385
386
        return \yii\grid\GridView::widget([
387
            'layout' => '{items}',
388
            'showOnEmpty' => false,
389
            'emptyText' => '',
390
            'tableOptions' => ['class' => 'table table-striped table-condensed'],
391
            'headerRowOptions' => [
392
                'style' => 'display: none;',
393
            ],
394
            'dataProvider' => new ArrayDataProvider(['allModels' => $models, 'pagination' => false]),
395
            'columns' => [
396
                [
397
                    'attribute' => 'typeLabel',
398
                ],
399
                [
400
                    'attribute' => 'value',
401
                    'format' => 'html',
402
                ],
403
            ],
404
        ]);
405
    }
406
407
    private function getTypeOfSale($model): string
408
    {
409
        $html = '';
410
        $badgeColors = [
411
            'leasing' => 'bg-orange',
412
            'rent' => 'bg-purple',
413
            'sold' => 'bg-olive',
414
        ];
415
        if ($model->prices) {
416
            foreach ($model->prices as $saleType => $prices) {
417
                $html .= ArraySpoiler::widget([
418
                    'data' => Sort::by($prices, function ($price) {
419
                        $order = ['CHASSIS', 'MOTHERBOARD', 'CPU', 'RAM', 'HDD', 'SSD'];
420
                        $type = substr($price['part'], 0, strpos($price['part'], ':'));
421
                        $key = array_search($type, $order, true);
422
                        if ($key !== false) {
423
                            return $key;
424
                        }
425
426
                        return INF;
427
                    }),
428
                    'delimiter' => '<br/>',
429
                    'visibleCount' => 0,
430
                    'button' => [
431
                        'label' => Yii::t('hipanel:server', $saleType) . ' ' . (count($prices)),
432
                        'tag' => 'button',
433
                        'type' => 'button',
434
                        'class' => "btn btn-xs {$badgeColors[$saleType]}",
435
                        'popoverOptions' => [
436
                            'html' => true,
437
                            'placement' => 'bottom',
438
                            'title' => Yii::t('hipanel:stock', 'Parts'),
439
                            'template' => '
440
                                <div class="popover" role="tooltip">
441
                                    <div class="arrow"></div>
442
                                    <h3 class="popover-title"></h3>
443
                                    <div class="popover-content" style="height: 25rem; overflow-x: scroll;"></div>
444
                                </div>
445
                            ',
446
447
                        ],
448
                    ],
449
                    'formatter' => function ($item) {
450
                        $title = $item['part'];
451
                        if ($item['serialno']) {
452
                            $title .= ': ' .$item['serialno'];
453
                        }
454
455
                        return Html::a(
456
                            $title,
457
                            ['@part/view', 'id' => $item['part_id']],
458
                            ['class' => 'text-nowrap', 'target' => '_blank']
459
                        );
460
                    },
461
                ]);
462
            }
463
        }
464
465
        return $html;
466
    }
467
}
468