Completed
Push — master ( 9add23...da9c6f )
by Andrii
04:58
created

Server   A

Complexity

Total Complexity 40

Size/Duplication

Total Lines 351
Duplicated Lines 0 %

Test Coverage

Coverage 1.98%

Importance

Changes 0
Metric Value
wmc 40
eloc 135
dl 0
loc 351
ccs 2
cts 101
cp 0.0198
rs 9.2
c 0
b 0
f 0

30 Methods

Rating   Name   Duplication   Size   Complexity  
A getSwitches() 0 3 1
A isLiveCDSupported() 0 3 1
A isOperable() 0 7 3
A goodStates() 0 3 1
A rules() 0 69 1
A isDedicatedDevice() 0 3 1
A canFullRefuse() 0 7 2
A isStateGood() 0 3 1
A groupUsesForCharts() 0 3 1
A getConsumptions() 0 3 1
A isVNCSupported() 0 3 1
A checkOperable() 0 7 2
A getIps() 0 7 2
A scenarioActions() 0 5 1
A getUses() 0 3 1
A getIsBlocked() 0 3 1
A isPwChangeSupported() 0 3 1
A canEnableVNC() 0 3 2
A isVirtualDevice() 0 3 1
A attributeLabels() 0 26 1
A getBindings() 0 4 1
A getHardwareSettings() 0 3 1
A getTypeOptions() 0 3 1
A getMonitoringSettings() 0 3 1
A getBinding() 0 7 2
A getPanel() 0 11 4
A getSoftwareSettings() 0 3 1
A getStateOptions() 0 6 1
A find() 0 4 1
A canAssignHubs() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Server often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Server, and based on these observations, apply Extract Interface, too.

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\models;
12
13
use hipanel\models\Ref;
14
use hipanel\modules\hosting\models\Ip;
0 ignored issues
show
Bug introduced by
The type hipanel\modules\hosting\models\Ip 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...
15
use hipanel\modules\server\helpers\ServerHelper;
16
use hipanel\modules\server\models\query\ServerQuery;
17
use hipanel\validators\EidValidator;
18
use hipanel\validators\RefValidator;
19
use Yii;
20
use yii\base\NotSupportedException;
21
22
class Server extends \hipanel\base\Model
23
{
24
    use \hipanel\base\ModelTrait;
25
26
    const STATE_OK = 'ok';
27
    const STATE_DISABLED = 'disabled';
28
    const STATE_BLOCKED = 'blocked';
29
    const STATE_DELETED = 'deleted';
30
31
    const VIRTUAL_DEVICES = ['avds', 'svds', 'ovds'];
32
33
    const SVDS_TYPES = ['avds', 'svds'];
34
35
    const DEFAULT_PANEL = 'rcp';
36
37 1
    public function rules()
38
    {
39
        return [
40 1
            [['id', 'tariff_id', 'client_id', 'seller_id'], 'integer'],
41
            [['osimage'], EidValidator::class],
42
            [['panel'], RefValidator::class],
43
            [
44
                [
45
                    'name', 'dc',
46
                    'client', 'seller',
47
                    'os', 'panel', 'rcp',
48
                    'parent_tariff', 'tariff', 'tariff_note', 'discounts',
49
                    'request_state', 'request_state_label',
50
                    'autorenewal',
51
                    'type', 'type_label', 'state', 'state_label', 'statuses',
52
                    'block_reason_label',
53
                    'running_task',
54
                    'ip', 'ips_num', 'mac',
55
                    'acs_num', 'del_acs_num', 'wizzarded',
56
                    'vnc',
57
                    'note', 'label', 'hwsummary', 'order_no',
58
                ],
59
                'safe',
60
            ],
61
            [['show_del', 'show_nic', 'show_vds', 'show_jail'], 'boolean'],
62
            [['switches', 'rack', 'net', 'kvm', 'pdu', 'ipmi'], 'safe'],
63
            [['last_expires', 'expires', 'status_time'], 'date'],
64
            [['time'], 'date', 'format' => 'php:Y-m-d H:i:s'],
65
            [
66
                ['state'],
67
                'isOperable',
68
                'on' => [
69
                    'reinstall',
70
                    'reboot',
71
                    'reset',
72
                    'shutdown',
73
                    'power-off',
74
                    'power-on',
75
                    'boot-live',
76
                    'regen-root-password',
77
                    'reset-password',
78
                ],
79
            ],
80
            [
81
                ['id'],
82
                'required',
83
                'on' => [
84
                    'refuse', 'delete', 'enable-autorenewal',
85
                    'enable-vnc', 'set-note', 'set-label',
86
                    'enable-block', 'disable-block', 'clear-resources',
87
                    'flush-switch-graphs',
88
                ],
89
            ],
90
            [
91
                ['id'],
92
                'integer',
93
                'on' => [
94
                    'refuse', 'delete', 'enable-autorenewal',
95
                    'enable-vnc', 'set-note', 'set-label',
96
                    'enable-block', 'disable-block',
97
                ],
98
            ],
99
            [['id', 'osimage'], 'required', 'on' => ['reinstall']],
100
            [['id', 'osimage'], 'required', 'on' => ['boot-live']],
101
            [['type', 'comment'], 'required', 'on' => ['enable-block', 'disable-block']],
102
103
            [['tariff_id', 'sale_time'], 'required', 'on' => ['sale']],
104
            [['move_accounts'], 'safe', 'on' => ['sale']],
105
            [['id', 'type'], 'required', 'on' => ['set-type']],
106
        ];
107
    }
108
109
    /**
110
     * Determine good server states.
111
     *
112
     * @return array
113
     */
114
    public function goodStates()
115
    {
116
        return [static::STATE_OK, static::STATE_DISABLED];
117
    }
118
119
    /**
120
     * @return bool
121
     */
122
    public function isOperable()
123
    {
124
        if ($this->running_task || !$this->isStateGood()) {
0 ignored issues
show
Bug Best Practice introduced by
The property running_task does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
125
            return false;
126
        }
127
128
        return true;
129
    }
130
131
    public function canEnableVNC()
132
    {
133
        return $this->isVNCSupported() && $this->isStateGood();
134
    }
135
136
    public function isStateGood()
137
    {
138
        return in_array($this->state, $this->goodStates(), true);
0 ignored issues
show
Bug Best Practice introduced by
The property state does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
139
    }
140
141
    /**
142
     * Checks whether server supports VNC.
143
     *
144
     * @return bool
145
     */
146
    public function isVNCSupported()
147
    {
148
        return in_array($this->type, static::SVDS_TYPES, true);
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
149
    }
150
151
    /**
152
     * Checks whether server supports root password change.
153
     *
154
     * @return bool
155
     */
156
    public function isPwChangeSupported()
157
    {
158
        return $this->type === 'ovds';
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
159
    }
160
161
    /**
162
     * Checks whether server supports LiveCD.
163
     *
164
     * @return bool
165
     */
166
    public function isLiveCDSupported()
167
    {
168
        return in_array($this->type, static::SVDS_TYPES, true);
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
169
    }
170
171
    /**
172
     * Check whether server is virtual.
173
     *
174
     * @return bool
175
     */
176
    public function isVirtualDevice()
177
    {
178
        return in_array($this->type, static::VIRTUAL_DEVICES, true);
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
179
    }
180
181
    /**
182
     * Check whether server is dedicated.
183
     *
184
     * @return bool
185
     */
186
    public function isDedicatedDevice()
187
    {
188
        return $this->type === 'dedicated';
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
189
    }
190
191
    public function getIsBlocked()
192
    {
193
        return $this->state === static::STATE_BLOCKED;
0 ignored issues
show
Bug Best Practice introduced by
The property state does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
194
    }
195
196
    /**
197
     * Checks whether server can be operated not.
198
     *
199
     * @throws NotSupportedException
200
     * @return bool
201
     * @see isOperable()
202
     */
203
    public function checkOperable()
204
    {
205
        if (!$this->isOperable()) {
206
            throw new NotSupportedException(Yii::t('hipanel:server', 'Server already has a running task. Can not start new.'));
207
        }
208
209
        return true;
210
    }
211
212
    /**
213
     * {@inheritdoc}
214
     */
215
    public function scenarioActions()
216
    {
217
        return [
218
            'reinstall' => 'resetup',
219
            'reset-password' => 'regen-root-password',
220
        ];
221
    }
222
223
    /**
224
     * During 5 days after the last expiration client is able to refuse server with full refund.
225
     * Method checks, whether 5 days passed.
226
     * @return bool
227
     */
228
    public function canFullRefuse()
229
    {
230
        if (!is_numeric($this->last_expires)) {
0 ignored issues
show
Bug Best Practice introduced by
The property last_expires does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
231
            return null; // In case server is not sold
232
        }
233
234
        return (time() - Yii::$app->formatter->asTimestamp($this->last_expires)) / 3600 / 24 < 5;
235
    }
236
237
    public function groupUsesForCharts()
238
    {
239
        return ServerHelper::groupUsesForChart($this->uses);
0 ignored issues
show
Bug Best Practice introduced by
The property uses does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
240
    }
241
242
    public function getUses()
243
    {
244
        return $this->hasMany(ServerUse::class, ['object_id' => 'id']);
245
    }
246
247
    public function getIps()
248
    {
249
        if (Yii::getAlias('@ip', false)) {
250
            return $this->hasMany(Ip::class, ['device_id' => 'id'])->joinWith('links');
251
        }
252
253
        return [];
254
    }
255
256
    public function getSwitches()
257
    {
258
        return $this->hasMany(Server::class, ['obj_id' => 'id']);
259
    }
260
261
    public function getConsumptions()
262
    {
263
        return $this->hasMany(Consumption::class, ['object_id' => 'id'])->indexBy('type');
264
    }
265
266
    public function getBindings()
267
    {
268
        return $this->hasMany(Binding::class, ['device_id' => 'id'])->indexBy(function ($binding) {
269
            return $binding->typeWithNo;
270
        });
271
    }
272
273
    public function getMonitoringSettings()
274
    {
275
        return $this->hasOne(MonitoringSettings::class, ['id' => 'id']);
276
    }
277
278
    public function getHardwareSettings()
279
    {
280
        return $this->hasOne(HardwareSettings::class, ['id' => 'id']);
281
    }
282
283
    public function getSoftwareSettings()
284
    {
285
        return $this->hasOne(SoftwareSettings::class, ['id' => 'id']);
286
    }
287
288
    public function getBinding($type)
289
    {
290
        if (!isset($this->bindings[$type])) {
0 ignored issues
show
Bug Best Practice introduced by
The property bindings does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
291
            return null;
292
        }
293
294
        return $this->bindings[$type];
295
    }
296
297
    public function getPanel()
298
    {
299
        if ($this->state === self::STATE_DISABLED) {
0 ignored issues
show
Bug Best Practice introduced by
The property state does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
300
            return null;
301
        }
302
303
        if ($this->panel || $this->isVirtualDevice()) {
0 ignored issues
show
Bug Best Practice introduced by
The property panel does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
304
            return $this->panel;
305
        }
306
307
        return self::DEFAULT_PANEL;
308
    }
309
310
    /**
311
     * {@inheritdoc}
312
     */
313
    public function attributeLabels()
314
    {
315
        return $this->mergeAttributeLabels([
316
            'remoteid' => Yii::t('hipanel:server', 'Remote ID'),
317
            'name' => Yii::t('hipanel:server', 'Name'),
318
            'dc' => Yii::t('hipanel:server', 'DC'),
319
            'net' => Yii::t('hipanel:server', 'Switch'),
320
            'kvm' => Yii::t('hipanel:server', 'KVM'),
321
            'pdu' => Yii::t('hipanel:server', 'APC'),
322
            'rack' => Yii::t('hipanel:server', 'Rack'),
323
            'ipmi' => Yii::t('hipanel:server', 'IPMI'),
324
            'status_time' => Yii::t('hipanel:server', 'Status update time'),
325
            'block_reason_label' => Yii::t('hipanel:server', 'Block reason label'),
326
            'request_state_label' => Yii::t('hipanel:server', 'Request state label'),
327
            'mac' => Yii::t('hipanel:server', 'MAC'),
328
            'ips' => Yii::t('hipanel:server', 'IPs'),
329
            'label' => Yii::t('hipanel:server', 'Internal note'),
330
            'os' => Yii::t('hipanel:server', 'OS'),
331
            'comment' => Yii::t('hipanel:server', 'Comment'),
332
            'hwsummary' => Yii::t('hipanel:server', 'HW summary'),
333
            'sale_time' => Yii::t('hipanel:server', 'Sale time'),
334
            'expires' => Yii::t('hipanel:server', 'Expires'),
335
            'tariff_id' => Yii::t('hipanel:server', 'Tariff'),
336
            'order_no' => Yii::t('hipanel:server', 'Order'),
337
            'move_accounts' => Yii::t('hipanel:server', 'Move accounts to new client'),
338
            'server' => Yii::t('hipanel:server', 'Server name'),
339
        ]);
340
    }
341
342
    public function getTypeOptions(): array
343
    {
344
        return Ref::getList('type,device,server', 'hipanel:server');
345
    }
346
347
    public function getStateOptions(): array
348
    {
349
        return [
350
            self::STATE_DISABLED    => Yii::t('hipanel:server', 'Disabled'),
351
            self::STATE_OK          => Yii::t('hipanel:server', 'Ok'),
352
            self::STATE_BLOCKED     => Yii::t('hipanel:server', 'Blocked'),
353
        ];
354
    }
355
356
    /**
357
     * Check if you can assign hubs
358
     * @return bool
359
     */
360
    public function canAssignHubs(): bool
361
    {
362
        return $this->type !== 'nic'; // XXX todo: need to add more types
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist on hipanel\modules\server\models\Server. Since you implemented __get, consider adding a @property annotation.
Loading history...
363
    }
364
365
    /**
366
     * {@inheritdoc}
367
     * @return ServerQuery
368
     */
369
    public static function find($options = [])
370
    {
371
        return new ServerQuery(get_called_class(), [
372
            'options' => $options,
373
        ]);
374
    }
375
}
376