Completed
Push — master ( 162d03...dee7fc )
by Dmitry
10:00
created

ServerController::actions()   C

Complexity

Conditions 12
Paths 1

Size

Total Lines 308
Code Lines 219

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 57
CRAP Score 12

Importance

Changes 34
Bugs 7 Features 9
Metric Value
c 34
b 7
f 9
dl 0
loc 308
ccs 57
cts 57
cp 1
rs 5.034
cc 12
eloc 219
nc 1
nop 0
crap 12

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\PrepareBulkAction;
17
use hipanel\actions\ProxyAction;
18
use hipanel\actions\RedirectAction;
19
use hipanel\actions\RenderAction;
20
use hipanel\actions\RenderJsonAction;
21
use hipanel\actions\RequestStateAction;
22
use hipanel\actions\SearchAction;
23
use hipanel\actions\SmartDeleteAction;
24
use hipanel\actions\SmartUpdateAction;
25
use hipanel\actions\ValidateFormAction;
26
use hipanel\actions\ViewAction;
27
use hipanel\base\CrudController;
28
use hipanel\models\Ref;
29
use hipanel\modules\finance\models\Tariff;
30
use hipanel\modules\server\cart\ServerRenewProduct;
31
use hipanel\modules\server\helpers\ServerHelper;
32
use hipanel\modules\server\models\Osimage;
33
use hipanel\modules\server\models\Server;
34
use hipanel\modules\server\models\ServerUseSearch;
35
use hiqdev\yii2\cart\actions\AddToCartAction;
36
use Yii;
37
use yii\base\Event;
38
use yii\helpers\ArrayHelper;
39
use yii\web\NotFoundHttpException;
40
41
class ServerController extends CrudController
42
{
43 1
    public function actions()
44
    {
45
        return [
46
            'index' => [
47
                'class' => IndexAction::class,
48
                'findOptions' => ['with_requests' => true, 'with_discounts' => true],
49
                'on beforePerform' => function (Event $event) {
50
                    /** @var \hipanel\actions\SearchAction $action */
51
                    $action = $event->sender;
52
                    $dataProvider = $action->getDataProvider();
53
                    $dataProvider->query->joinWith('ips');
54
55
                    $dataProvider->query
56
                        ->andWhere(['with_requests' => 1])
57
                        ->andWhere(['with_discounts' => 1])
58
                        ->andWhere(['with_ips' => 1])
59
                        ->select(['*']);
60 1
                },
61
                'data' => function ($action) {
62
                    return [
63
                        'states' => $action->controller->getStates(),
64
                    ];
65 1
                },
66
                'filterStorageMap' => [
67
                    'name_like' => 'server.server.name',
68
                    'ips' => 'hosting.ip.ip_in',
69
                    'state' => 'server.server.state',
70
                    'client_id' => 'client.client.id',
71
                    'seller_id' => 'client.client.seller_id',
72
                ],
73 1
            ],
74
            'search' => [
75
                'class' => SearchAction::class,
76
            ],
77
            'view' => [
78
                'class' => ViewAction::class,
79
                'on beforePerform' => function (Event $event) {
80
                    /** @var \hipanel\actions\SearchAction $action */
81
                    $action = $event->sender;
82
                    $dataProvider = $action->getDataProvider();
83
                    $dataProvider->query->joinWith('uses');
84
                    $dataProvider->query->joinWith('ips');
85
86
                    // TODO: ipModule is not wise yet. Redo
87
                    $dataProvider->query
88
                        ->andWhere(['with_requests' => 1])
89
                        ->andWhere(['show_deleted' => 1])
90
                        ->andWhere(['with_discounts' => 1])
91
                        ->andWhere(['with_uses' => 1])
92
                        ->andWhere(['with_ips' => 1])
93
                        ->select(['*']);
94 1
                },
95
                'data' => function ($action) {
96
                    /**
97
                     * @var
98
                     * @var $model Server
99
                     */
100
                    $controller = $action->controller;
101
                    $model = $action->getModel();
102
                    $model->vnc = $controller->getVNCInfo($model);
103
104
                    $panels = $controller->getPanelTypes();
105
106
                    $tariff = Yii::$app->cache->getAuthTimeCached(3600, [$model->tariff_id], function ($tariff_id) {
107
                        return Tariff::find()->where([
108
                            'id' => $tariff_id,
109
                            'show_final' => true,
110
                            'show_deleted' => true,
111
                            'with_resources' => true,
112
                        ])->joinWith('resources')->one();
113
                    });
114
115
                    $ispSupported = false;
116
                    if ($tariff !== null) {
117
                        foreach ($tariff->getResources() as $resource) {
118
                            if ($resource->type === 'isp' && $resource->quantity > 0) {
119
                                $ispSupported = true;
120
                            }
121
                        }
122
                    }
123
124
                    $osimages = $controller->getOsimages($model);
125
                    $groupedOsimages = ServerHelper::groupOsimages($osimages, $ispSupported);
126
127
                    if ($model->isLiveCDSupported()) {
128
                        $osimageslivecd = $controller->getOsimagesLiveCd();
129
                    }
130
131
                    $blockReasons = $controller->getBlockReasons();
132
133
                    return compact([
134
                        'model',
135
                        'osimages',
136
                        'osimageslivecd',
137
                        'groupedOsimages',
138
                        'panels',
139
                        'blockReasons',
140
                    ]);
141 1
                },
142
            ],
143
            'requests-state' => [
144 1
                'class' => RequestStateAction::className(),
145 1
                'model' => Server::className(),
146
            ],
147
            'set-note' => [
148
                'class' => SmartUpdateAction::class,
149 1
                'success' => Yii::t('hipanel/server', 'Note changed'),
150 1
                'error' => Yii::t('hipanel/server', 'Failed to change note'),
151
            ],
152
            'set-label' => [
153
                'class' => SmartUpdateAction::class,
154 1
                'success' => Yii::t('hipanel/server', 'Internal note changed'),
155 1
                'error' => Yii::t('hipanel/server', 'Failed to change internal note'),
156
            ],
157
            'set-lock' => [
158
                'class' => RenderAction::class,
159 1
                'success' => Yii::t('hipanel/server', 'Record was changed'),
160 1
                'error' => Yii::t('hipanel/server', 'Error occurred'),
161
                'POST pjax' => [
162
                    'save' => true,
163
                    'success' => [
164
                        'class' => ProxyAction::class,
165
                        'action' => 'index',
166
                    ],
167
                ],
168
                'POST' => [
169
                    'save' => true,
170
                    'success' => [
171
                        'class' => RenderJsonAction::class,
172
                        'return' => function ($action) {
173
                            /** @var \hipanel\actions\Action $action */
174
                            return $action->collection->models;
175 1
                        },
176
                    ],
177
                ],
178
            ],
179
            'enable-vnc' => [
180
                'class' => ViewAction::class,
181 1
                'view' => '_vnc',
182
                'data' => function ($action) {
183
                    $model = $action->getModel();
184
                    $model->checkOperable();
185
                    $model->vnc = $action->controller->getVNCInfo($model, true);
186
                    return [];
187 1
                },
188
            ],
189
            'reboot' => [
190
                'class' => SmartUpdateAction::class,
191 1
                'success' => Yii::t('hipanel/server', 'Reboot task has been successfully added to queue'),
192 1
                'error' => Yii::t('hipanel/server', 'Error during the rebooting'),
193
            ],
194
            'reset' => [
195
                'class' => SmartUpdateAction::class,
196 1
                'success' => Yii::t('hipanel/server', 'Reset task has been successfully added to queue'),
197 1
                'error' => Yii::t('hipanel/server', 'Error during the resetting'),
198
            ],
199
            'shutdown' => [
200
                'class' => SmartUpdateAction::class,
201 1
                'success' => Yii::t('hipanel/server', 'Shutdown task has been successfully added to queue'),
202 1
                'error' => Yii::t('hipanel/server', 'Error during the shutting down'),
203
            ],
204
            'power-off' => [
205
                'class' => SmartUpdateAction::class,
206 1
                'success' => Yii::t('hipanel/server', 'Power off task has been successfully added to queue'),
207 1
                'error' => Yii::t('hipanel/server', 'Error during the turning power off'),
208
            ],
209
            'power-on' => [
210
                'class' => SmartUpdateAction::class,
211 1
                'success' => Yii::t('hipanel/server', 'Power on task has been successfully added to queue'),
212 1
                'error' => Yii::t('hipanel/server', 'Error during the turning power on'),
213
            ],
214
            'reset-password' => [
215
                'class' => SmartUpdateAction::class,
216 1
                'success' => Yii::t('hipanel/server', 'Root password reset task has been successfully added to queue'),
217 1
                'error' => Yii::t('hipanel/server', 'Error during the resetting root password'),
218
            ],
219
            'enable-block' => [
220
                'class' => SmartUpdateAction::class,
221 1
                'success' => Yii::t('hipanel/server', 'Server was blocked successfully'),
222 1
                'error' => Yii::t('hipanel/server', 'Error during the server blocking'),
223
            ],
224
            'disable-block' => [
225
                'class' => SmartUpdateAction::class,
226 1
                'success' => Yii::t('hipanel/server', 'Server was unblocked successfully'),
227 1
                'error' => Yii::t('hipanel/server', 'Error during the server unblocking'),
228
            ],
229
            'refuse' => [
230
                'class' => SmartUpdateAction::class,
231 1
                'success' => Yii::t('hipanel/server', 'You have refused the service'),
232 1
                'error' => Yii::t('hipanel/server', 'Error during the refusing the service'),
233
            ],
234
            'enable-autorenewal' => [
235
                'class' => SmartUpdateAction::class,
236 1
                'success' => Yii::t('hipanel/server', 'Server renewal enabled successfully'),
237 1
                'error' => Yii::t('hipanel/server', 'Error during the renewing the service'),
238
            ],
239
            'reinstall' => [
240
                'class' => SmartUpdateAction::class,
241
                'on beforeSave' => function (Event $event) {
242
                    /** @var Action $action */
243
                    $action = $event->sender;
244
                    foreach ($action->collection->models as $model) {
245
                        $model->osimage = Yii::$app->request->post('osimage');
246
                        $model->panel = Yii::$app->request->post('panel');
247
                    }
248 1
                },
249 1
                'success' => Yii::t('hipanel/server', 'Server reinstalling task has been successfully added to queue'),
250 1
                'error' => Yii::t('hipanel/server', 'Error during the server reinstalling'),
251
            ],
252
            'boot-live' => [
253
                'class' => SmartUpdateAction::class,
254
                'on beforeSave' => function (Event $event) {
255
                    /** @var Action $action */
256
                    $action = $event->sender;
257
                    foreach ($action->collection->models as $model) {
258
                        $model->osimage = Yii::$app->request->post('osimage');
259
                    }
260 1
                },
261 1
                'success' => Yii::t('hipanel/server', 'Live CD booting task has been successfully added to queue'),
262 1
                'error' => Yii::t('hipanel/server', 'Error during the booting live CD'),
263
            ],
264
            'validate-form' => [
265
                'class' => ValidateFormAction::class,
266
            ],
267
            'buy' => [
268
                'class' => RedirectAction::class,
269 1
                'url' => Yii::$app->params['orgUrl'],
270
            ],
271
            'add-to-cart-renewal' => [
272
                'class' => AddToCartAction::class,
273
                'productClass' => ServerRenewProduct::class,
274
            ],
275
            'delete' => [
276
                'class' => SmartDeleteAction::class,
277 1
                'success' => Yii::t('hipanel/server', 'Server was deleted successfully'),
278 1
                'error' => Yii::t('hipanel/server', 'Failed to delete server'),
279
            ],
280
            'bulk-delete-modal' => [
281
                'class' => PrepareBulkAction::class,
282
                'scenario' => 'delete',
283
                'view' => '_bulkDelete',
284
            ],
285
            'bulk-enable-block' => [
286
                'class' => SmartUpdateAction::class,
287 1
                'scenario' => 'enable-block',
288 1
                'success' => Yii::t('hipanel/server', 'Servers were blocked successfully'),
289 1
                'error' => Yii::t('hipanel/server', 'Error during the servers blocking'),
290
                'POST html' => [
291
                    'save'    => true,
292
                    'success' => [
293
                        'class' => RedirectAction::class,
294
                    ],
295
                ],
296
                'on beforeSave' => function (Event $event) {
297
                    /** @var \hipanel\actions\Action $action */
298
                    $action = $event->sender;
299
                    $type = Yii::$app->request->post('type');
300
                    $comment = Yii::$app->request->post('comment');
301
                    if (!empty($type)) {
302
                        foreach ($action->collection->models as $model) {
303
                            $model->setAttributes([
304
                                'type' => $type,
305
                                'comment' => $comment,
306
                            ]);
307
                        }
308
                    }
309 1
                },
310
            ],
311
            'bulk-enable-block-modal' => [
312
                'class' => PrepareBulkAction::class,
313 1
                'scenario' => 'enable-block',
314 1
                'view' => '_bulkEnableBlock',
315
                'data' => function ($action, $data) {
316
                    return array_merge($data, [
317
                        'blockReasons' => $this->getBlockReasons(),
318
                    ]);
319 1
                },
320
            ],
321
            'bulk-disable-block' => [
322
                'class' => SmartUpdateAction::class,
323 1
                'scenario' => 'disable-block',
324 1
                'success' => Yii::t('hipanel/server', 'Servers were unblocked successfully'),
325 1
                'error' => Yii::t('hipanel/server', 'Error during the servers unblocking'),
326
                'POST html' => [
327
                    'save'    => true,
328
                    'success' => [
329
                        'class' => RedirectAction::class,
330
                    ],
331
                ],
332
                'on beforeSave' => function (Event $event) {
333
                    /** @var \hipanel\actions\Action $action */
334
                    $action = $event->sender;
335
                    $comment = Yii::$app->request->post('comment');
336
                    if (!empty($type)) {
0 ignored issues
show
Bug introduced by
The variable $type seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
337
                        foreach ($action->collection->models as $model) {
338
                            $model->setAttribute('comment', $comment);
339
                        }
340
                    }
341 1
                },
342
            ],
343
            'bulk-disable-block-modal' => [
344
                'class' => PrepareBulkAction::class,
345
                'scenario' => 'disable-block',
346
                'view' => '_bulkDisableBlock',
347
            ],
348
349
        ];
350
    }
351
352
    /**
353
     * Gets info of VNC on the server.
354
     *
355
     * @param Server $model
356
     * @param bool $enable
357
     *
358
     * @return array
359
     */
360
    public function getVNCInfo($model, $enable = false)
361
    {
362
        $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...
363
        if (($vnc['endTime'] > time() || $enable) && $model->isOperable()) {
364
            $vnc['enabled'] = true;
365
            $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...
366
        }
367
368
        return $vnc;
369
    }
370
371
    public function actionDrawChart()
372
    {
373
        $post = Yii::$app->request->post();
374
        if (!in_array($post['type'], ['traffic', 'bandwidth'], true)) {
375
            throw new NotFoundHttpException();
376
        }
377
378
        $searchModel = new ServerUseSearch();
379
        $dataProvider = $searchModel->search([]);
380
        $dataProvider->pagination = false;
381
        $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...
382
        $dataProvider->query->andWhere($post);
383
        $models = $dataProvider->getModels();
384
385
        list($labels, $data) = ServerHelper::groupUsesForChart($models);
0 ignored issues
show
Documentation introduced by
$models is of type array|null, but the function expects a array<integer,object<hip...rver\models\ServerUse>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
386
387
        return $this->renderAjax('_' . $post['type'] . '_consumption', [
388
            'labels' => $labels,
389
            'data' => $data,
390
        ]);
391
    }
392
393
    /**
394
     * Gets OS images.
395
     *
396
     * @param Server $model
397
     * @throws NotFoundHttpException
398
     * @return array
399
     */
400
    protected function getOsimages(Server $model = null)
401
    {
402
        if ($model !== null) {
403
            $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...
404
        } else {
405
            $type = null;
406
        }
407
408
        $models = ServerHelper::getOsimages($type);
409
410
        if ($models === null) {
411
            throw new NotFoundHttpException('The requested page does not exist.');
412
        }
413
414
        return $models;
415
    }
416
417
    protected function getOsimagesLiveCd()
418
    {
419
        $models = Yii::$app->cache->getTimeCached(3600, [true], function ($livecd) {
420
            return Osimage::findAll(['livecd' => $livecd]);
421
        });
422
423
        if ($models !== null) {
424
            return $models;
425
        }
426
427
        throw new NotFoundHttpException('The requested page does not exist.');
428
    }
429
430
    protected function getPanelTypes()
431
    {
432
        return ServerHelper::getPanels();
433
    }
434
435
    protected function getStates()
436
    {
437
        $states = Ref::getList('state,device');
438
        return $states;
439
    }
440
}
441