Completed
Push — master ( cf838f...441ca2 )
by Dmitry
04:31
created

ServerController::getGroupedOsimages()   C

Complexity

Conditions 12
Paths 49

Size

Total Lines 62
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 2 Features 0
Metric Value
c 8
b 2
f 0
dl 0
loc 62
rs 6.2072
cc 12
eloc 42
nc 49
nop 2

How to fix   Long Method    Complexity   

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
/*
4
 * Server module for HiPanel
5
 *
6
 * @link      https://github.com/hiqdev/hipanel-module-server
7
 * @package   hipanel-module-server
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2015-2016, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hipanel\modules\server\controllers;
13
14
use hipanel\actions\Action;
15
use hipanel\actions\IndexAction;
16
use hipanel\actions\ProxyAction;
17
use hipanel\actions\RedirectAction;
18
use hipanel\actions\RenderAction;
19
use hipanel\actions\RenderJsonAction;
20
use hipanel\actions\RequestStateAction;
21
use hipanel\actions\SearchAction;
22
use hipanel\actions\SmartUpdateAction;
23
use hipanel\actions\ValidateFormAction;
24
use hipanel\actions\ViewAction;
25
use hipanel\base\CrudController;
26
use hipanel\models\Ref;
27
use hipanel\modules\finance\models\Tariff;
28
use hipanel\modules\server\cart\ServerRenewProduct;
29
use hipanel\modules\server\helpers\ServerHelper;
30
use hipanel\modules\server\models\Osimage;
31
use hipanel\modules\server\models\Server;
32
use hipanel\modules\server\models\ServerUseSearch;
33
use hiqdev\yii2\cart\actions\AddToCartAction;
34
use Yii;
35
use yii\base\Event;
36
use yii\helpers\ArrayHelper;
37
use yii\web\NotFoundHttpException;
38
39
class ServerController extends CrudController
40
{
41
    public function actions()
42
    {
43
        return [
44
            'index' => [
45
                'class' => IndexAction::class,
46
                'findOptions' => ['with_requests' => true, 'with_discounts' => true],
47
                'on beforePerform' => function (Event $event) {
48
                    /** @var \hipanel\actions\SearchAction $action */
49
                    $action = $event->sender;
50
                    $dataProvider = $action->getDataProvider();
51
                    $dataProvider->query->joinWith('ips');
52
53
                    $dataProvider->query
54
                        ->andWhere(['with_requests' => 1])
55
                        ->andWhere(['with_discounts' => 1])
56
                        ->andWhere(['with_ips' => 1])
57
                        ->select(['*']);
58
                },
59
                'data' => function ($action) {
60
                    return [
61
                        'states' => $action->controller->getStates(),
62
                    ];
63
                },
64
                'filterStorageMap' => [
65
                    'name_like' => 'server.server.name',
66
                    'ips' => 'hosting.ip.ip_in',
67
                    'state' => 'server.server.state',
68
                    'client_id' => 'client.client.id',
69
                    'seller_id' => 'client.client.seller_id',
70
                ],
71
            ],
72
            'search' => [
73
                'class' => SearchAction::class,
74
            ],
75
            'view' => [
76
                'class' => ViewAction::class,
77
                'on beforePerform' => function (Event $event) {
78
                    /** @var \hipanel\actions\SearchAction $action */
79
                    $action = $event->sender;
80
                    $dataProvider = $action->getDataProvider();
81
                    $dataProvider->query->joinWith('uses');
82
                    $dataProvider->query->joinWith('ips');
83
84
                    // TODO: ipModule is not wise yet. Redo
85
                    $dataProvider->query
86
                        ->andWhere(['with_requests' => 1])
87
                        ->andWhere(['show_deleted' => 1])
88
                        ->andWhere(['with_discounts' => 1])
89
                        ->andWhere(['with_uses' => 1])
90
                        ->andWhere(['with_ips' => 1])
91
                        ->select(['*']);
92
                },
93
                'data' => function ($action) {
94
                    /**
95
                     * @var $this
96
                     * @var $model Server
97
                     */
98
                    $controller = $action->controller;
99
                    $model = $action->getModel();
100
                    $model->vnc = $controller->getVNCInfo($model);
101
102
                    $panels = $controller->getPanelTypes();
103
104
                    $tariff = Yii::$app->cache->getAuthTimeCached(3600, [$model->tariff_id], function ($tariff_id) {
105
                        return Tariff::find()->where([
106
                            'id' => $tariff_id,
107
                            'show_final' => true,
108
                            'show_deleted' => true,
109
                            'with_resources' => true,
110
                        ])->joinWith('resources')->one();
111
                    });
112
113
                    $ispSupported = false;
114
                    if ($tariff !== null) {
115
                        foreach ($tariff->getResources() as $resource) {
116
                            if ($resource->type === 'isp' && $resource->quantity > 0) {
117
                                $ispSupported = true;
118
                            }
119
                        }
120
                    }
121
122
                    $osimages = $controller->getOsimages($model);
123
                    $grouped_osimages = $controller->getGroupedOsimages($osimages, $ispSupported);
124
125
                    if ($model->isLiveCDSupported()) {
126
                        $osimageslivecd = $controller->getOsimagesLiveCd();
127
                    }
128
129
                    $blockReasons = $controller->getBlockReasons();
130
131
                    return compact([
132
                        'model',
133
                        'osimages',
134
                        'osimageslivecd',
135
                        'grouped_osimages',
136
                        'panels',
137
                        'blockReasons',
138
                    ]);
139
                },
140
            ],
141
            'requests-state' => [
142
                'class' => RequestStateAction::className(),
143
                'model' => Server::className(),
144
            ],
145
            'set-note' => [
146
                'class' => SmartUpdateAction::class,
147
                'success' => Yii::t('hipanel/server', 'Note changed'),
148
                'error' => Yii::t('hipanel/server', 'Failed to change note'),
149
            ],
150
            'set-label' => [
151
                'class' => SmartUpdateAction::class,
152
                'success' => Yii::t('hipanel/server', 'Internal note changed'),
153
                'error' => Yii::t('hipanel/server', 'Failed to change internal note'),
154
            ],
155
            'set-lock' => [
156
                'class' => RenderAction::class,
157
                'success' => Yii::t('hipanel/server', 'Record was changed'),
158
                'error' => Yii::t('hipanel/server', 'Error occurred'),
159
                'POST pjax' => [
160
                    'save' => true,
161
                    'success' => [
162
                        'class' => ProxyAction::class,
163
                        'action' => 'index',
164
                    ],
165
                ],
166
                'POST' => [
167
                    'save' => true,
168
                    'success' => [
169
                        'class' => RenderJsonAction::class,
170
                        'return' => function ($action) {
171
                            /** @var \hipanel\actions\Action $action */
172
                            return $action->collection->models;
173
                        },
174
                    ],
175
                ],
176
            ],
177
            'enable-vnc' => [
178
                'class' => ViewAction::class,
179
                'view' => '_vnc',
180
                'data' => function ($action) {
181
                    $model = $action->getModel();
182
                    $model->checkOperable();
183
                    $model->vnc = $action->controller->getVNCInfo($model, true);
184
                    return [];
185
                },
186
            ],
187
            'reboot' => [
188
                'class' => SmartUpdateAction::class,
189
                'success' => Yii::t('hipanel/server', 'Reboot task has been successfully added to queue'),
190
                'error' => Yii::t('hipanel/server', 'Error during the rebooting'),
191
            ],
192
            'reset' => [
193
                'class' => SmartUpdateAction::class,
194
                'success' => Yii::t('hipanel/server', 'Reset task has been successfully added to queue'),
195
                'error' => Yii::t('hipanel/server', 'Error during the resetting'),
196
            ],
197
            'shutdown' => [
198
                'class' => SmartUpdateAction::class,
199
                'success' => Yii::t('hipanel/server', 'Shutdown task has been successfully added to queue'),
200
                'error' => Yii::t('hipanel/server', 'Error during the shutting down'),
201
            ],
202
            'power-off' => [
203
                'class' => SmartUpdateAction::class,
204
                'success' => Yii::t('hipanel/server', 'Power off task has been successfully added to queue'),
205
                'error' => Yii::t('hipanel/server', 'Error during the turning power off'),
206
            ],
207
            'power-on' => [
208
                'class' => SmartUpdateAction::class,
209
                'success' => Yii::t('hipanel/server', 'Power on task has been successfully added to queue'),
210
                'error' => Yii::t('hipanel/server', 'Error during the turning power on'),
211
            ],
212
            'reset-password' => [
213
                'class' => SmartUpdateAction::class,
214
                'success' => Yii::t('hipanel/server', 'Root password reset task has been successfully added to queue'),
215
                'error' => Yii::t('hipanel/server', 'Error during the resetting root password'),
216
            ],
217
            'enable-block' => [
218
                'class' => SmartUpdateAction::class,
219
                'success' => Yii::t('hipanel/server', 'Server was blocked successfully'),
220
                'error' => Yii::t('hipanel/server', 'Error during the server blocking'),
221
            ],
222
            'disable-block' => [
223
                'class' => SmartUpdateAction::class,
224
                'success' => Yii::t('hipanel/server', 'Server was unblocked successfully'),
225
                'error' => Yii::t('hipanel/server', 'Error during the server unblocking'),
226
            ],
227
            'refuse' => [
228
                'class' => SmartUpdateAction::class,
229
                'success' => Yii::t('hipanel/server', 'You have refused the service'),
230
                'error' => Yii::t('hipanel/server', 'Error during the refusing the service'),
231
            ],
232
            'enable-autorenewal' => [
233
                'class' => SmartUpdateAction::class,
234
                'success' => Yii::t('hipanel/server', 'Server renewal enabled successfully'),
235
                'error' => Yii::t('hipanel/server', 'Error during the renewing the service'),
236
            ],
237
            'reinstall' => [
238
                'class' => SmartUpdateAction::class,
239
                'on beforeSave' => function (Event $event) {
240
                    /** @var Action $action */
241
                    $action = $event->sender;
242
                    foreach ($action->collection->models as $model) {
243
                        $model->osimage = Yii::$app->request->post('osimage');
244
                        $model->panel = Yii::$app->request->post('panel');
245
                    }
246
                },
247
                'success' => Yii::t('hipanel/server', 'Server reinstalling task has been successfully added to queue'),
248
                'error' => Yii::t('hipanel/server', 'Error during the server reinstalling'),
249
            ],
250
            'boot-live' => [
251
                'class' => SmartUpdateAction::class,
252
                'on beforeSave' => function (Event $event) {
253
                    /** @var Action $action */
254
                    $action = $event->sender;
255
                    foreach ($action->collection->models as $model) {
256
                        $model->osimage = Yii::$app->request->post('osimage');
257
                    }
258
                },
259
                'success' => Yii::t('hipanel/server', 'Live CD booting task has been successfully added to queue'),
260
                'error' => Yii::t('hipanel/server', 'Error during the booting live CD'),
261
            ],
262
            'validate-form' => [
263
                'class' => ValidateFormAction::class,
264
            ],
265
            'buy' => [
266
                'class' => RedirectAction::class,
267
                'url' => Yii::$app->params['orgUrl'],
268
            ],
269
            'add-to-cart-renewal' => [
270
                'class' => AddToCartAction::class,
271
                'productClass' => ServerRenewProduct::class,
272
            ],
273
        ];
274
    }
275
276
    /**
277
     * Gets info of VNC on the server.
278
     *
279
     * @param Server $model
280
     * @param bool $enable
281
     *
282
     * @return array
283
     */
284
    public function getVNCInfo($model, $enable = false)
285
    {
286
        $vnc['endTime'] = strtotime('+8 hours', strtotime($model->statuses['serverEnableVNC']));
0 ignored issues
show
Documentation introduced by
The property statuses does not exist on object<hipanel\modules\server\models\Server>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Coding Style Comprehensibility introduced by
$vnc was never initialized. Although not strictly required by PHP, it is generally a good practice to add $vnc = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
287
        if (($vnc['endTime'] > time() || $enable) && $model->isOperable()) {
288
            $vnc['enabled'] = true;
289
            $vnc = ArrayHelper::merge($vnc, Server::perform('EnableVNC', ['id' => $model->id]));
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<hipanel\modules\server\models\Server>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
290
        }
291
292
        return $vnc;
293
    }
294
295
    public function actionDrawChart()
296
    {
297
        $post = Yii::$app->request->post();
298
        if (!in_array($post['type'], ['traffic', 'bandwidth'], true)) {
299
            throw new NotFoundHttpException();
300
        }
301
302
        $searchModel = new ServerUseSearch();
303
        $dataProvider = $searchModel->search([]);
304
        $dataProvider->pagination = false;
305
        $dataProvider->query->options = ['scenario' => 'get-uses'];
0 ignored issues
show
Bug introduced by
Accessing options on the interface yii\db\QueryInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
306
        $dataProvider->query->andWhere($post);
307
        $models = $dataProvider->getModels();
308
309
        list($labels, $data) = ServerHelper::groupUsesForChart($models);
310
311
        return $this->renderAjax('_' . $post['type'] . '_consumption', [
312
            'labels' => $labels,
313
            'data' => $data,
314
        ]);
315
    }
316
317
    /**
318
     * Gets OS images.
319
     *
320
     * @param Server $model
321
     * @throws NotFoundHttpException
322
     * @return array
323
     */
324
    protected function getOsimages(Server $model = null)
325
    {
326
        if ($model !== null) {
327
            $type = $model->type;
0 ignored issues
show
Documentation introduced by
The property type does not exist on object<hipanel\modules\server\models\Server>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
328
        } else {
329
            $type = null;
330
        }
331
332
        $models = ServerHelper::getOsimages($type);
333
334
        if ($models === null) {
335
            throw new NotFoundHttpException('The requested page does not exist.');
336
        }
337
338
        return $models;
339
    }
340
341
    protected function getOsimagesLiveCd()
342
    {
343
        $models = Yii::$app->cache->getTimeCached(3600, [true], function ($livecd) {
344
            return Osimage::findAll(['livecd' => $livecd]);
345
        });
346
347
        if ($models !== null) {
348
            return $models;
349
        }
350
351
        throw new NotFoundHttpException('The requested page does not exist.');
352
    }
353
354
    protected function getPanelTypes()
355
    {
356
        return ServerHelper::getPanels();
357
    }
358
359
    protected function getStates()
360
    {
361
        $states = Ref::getList('state,device');
362
        return $states;
363
    }
364
}
365