Test Setup Failed
Push — master ( f00c96...40c7b0 )
by eXeCUT
11:05
created

Edit   C

Complexity

Total Complexity 62

Size/Duplication

Total Lines 336
Duplicated Lines 4.76 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 62
lcom 1
cbo 3
dl 16
loc 336
rs 5.9493
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
D _run() 16 98 23
A getSession() 0 7 2
A getIsValidate() 0 4 2
A isSave() 0 6 4
A isSubmitted() 0 4 2
A getHeading() 0 14 2
A getCreateFormLabel() 0 7 1
A getEditFormLabel() 0 10 2
A getDefaultViewRendererConfig() 0 8 1
A setFormAction() 0 5 1
A getFormAction() 0 7 2
B redirectAfterSave() 0 28 5
B getData() 0 19 5
A getUrlParams() 0 13 2
A translate() 0 6 1
A getTemplateSuccessMessage() 0 10 2
A setFlash() 0 6 2
B getSuccessMessage() 0 24 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Edit 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Edit, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * User: execut
4
 * Date: 14.07.16
5
 * Time: 16:00
6
 */
7
8
namespace execut\actions\action\adapter;
9
10
11
use execut\actions\action\adapter\viewRenderer\DetailView;
12
use yii\bootstrap\Html;
13
use yii\helpers\ArrayHelper;
14
use yii\web\Application;
15
use yii\web\NotFoundHttpException;
16
17
class Edit extends Form
18
{
19
    public $modelClass = null;
20
    public $relations = [];
21
    public $additionalAttributes = [];
22
    public $requestType = self::MIXED;
23
    public $scenario = null;
24
    public $createFormLabel = 'Create';
25
    public $editFormLabel = 'Edit';
26
    public $labelTemplate = '{label}{closeButton}';
27
    public $urlParamsForRedirectAfterSave = [];
28
    public $closeButton = '<a href="./" class="pull-right btn btn-xs btn-primary glyphicon glyphicon-remove"></a>';
29
30
    public $isTrySaveFromGet = false;
31
    public $templateSuccessMessage = null;
32
    public $mode = 'edit';
33
    public $session = null;
34
35
    const EVENT_AFTER_FIND = 'afterFind';
36
    protected function _run() {
37
        $actionParams = $this->actionParams;
38
        if ($this->actionParams && (!empty($actionParams->get['id']) || !empty($actionParams->post['id']))) {
39
            $mode = $this->mode;
40
        } else {
41
            $mode = 'edit';
42
        }
43
44
        if (!empty($this->getData()['view'])) {
45
            $mode = 'view';
46
        }
47
48
        $model = $this->getModel();
49
        if (!$model) {
50
            throw new NotFoundHttpException('Record not founded');
51
        }
52
53
        $this->trigger(self::EVENT_AFTER_FIND);
54
        if ($this->scenario !== null) {
55
            $model->setScenario($this->scenario);
56
        }
57
58
        $isNewRecord = $model->isNewRecord;
59
        $result = parent::loadAndValidateForm();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (loadAndValidateForm() instead of _run()). Are you sure this is correct? If so, you might want to change this to $this->loadAndValidateForm().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
60
        if (is_array($result)) {
61
            $response = $this->getResponse([
62
                'content' => $result
63
            ]);
64
            if ($this->actionParams->isAjax && !$this->actionParams->isPjax) {
65
                $response->format = \yii\web\Response::FORMAT_JSON;
66
            }
67
68
            return $response;
69
        }
70
71
        if ($result === true && $this->isSave() && $this->isSubmitted()) {
72
            $model->save();
73
            $this->trigger('afterSave');
74
            if ($isNewRecord) {
75
                $this->trigger('afterCreate');
76
            } else {
77
                $this->trigger('afterUpdate');
78
            }
79
80
            $successMessage = $this->getSuccessMessage($isNewRecord);
81
            $this->setFlash($successMessage);
82 View Code Duplication
            if ($this->actionParams->isAjax && !$this->actionParams->isPjax) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
                return $this->getResponse([
84
                    'format' => \yii\web\Response::FORMAT_JSON,
85
                    'content' => [
86
                        'message' => $this->getSuccessMessage($isNewRecord),
87
                    ],
88
                ]);
89
            }
90
91
            $result = $this->redirectAfterSave();
92
            if ($result === false) {
93
                $result = [
94
                    'mode' => $mode,
95
                    'model' => $model
96
                ];
97
            }
98
        } else {
99 View Code Duplication
            if ($this->actionParams->isAjax && !$this->actionParams->isPjax) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
100
                return $this->getResponse([
101
                    'format' => \yii\web\Response::FORMAT_JSON,
102
                    'content' => [
103
                        'success' => true,
104
                    ],
105
                ]);
106
            }
107
108
            if (!empty($model->errors)) {
109
                $flash = Html::errorSummary($model, [
110
                    'encode' => false,
111
                ]);
112
113
                $this->setFlash($flash, 'danger');
114
            }
115
116
            $result = [
117
                'mode' => $mode,
118
                'model' => $model
119
            ];
120
        }
121
122
        if (\yii::$app->has('db') && $t = \yii::$app->db->transaction) {
123
            while ($t->getIsActive()) {
124
                $t->commit();
125
            }
126
        }
127
128
        $response = $this->getResponse([
129
            'content' => $result,
130
        ]);
131
132
        return $response;
133
    }
134
135
    protected function getSession() {
136
        if ($this->session === null) {
137
            return \yii::$app->session;
138
        }
139
140
        return $this->session;
141
    }
142
143
    public function getIsValidate()
144
    {
145
        return $this->isSave() && parent::getIsValidate(); // TODO: Change the autogenerated stub
146
    }
147
148
    protected function isSave() {
149
        $get = $this->actionParams->get;
150
        unset($get['id']);
151
152
        return (!empty($get) && $this->isTrySaveFromGet || (!empty($this->actionParams->post) && empty($this->actionParams->post['check'])));
153
    }
154
155
    protected function isSubmitted() {
156
        $data = $this->actionParams->getData();
157
        return !empty($data['apply']) || !empty($data['save']);
158
    }
159
160
    protected function getHeading() {
161
        if ($this->model->isNewRecord) {
162
            $editFormLabel = $this->getCreateFormLabel();
163
        } else {
164
            $editFormLabel = $this->getEditFormLabel($this->model);
165
        }
166
167
        $editFormLabel  = strtr($this->labelTemplate, [
168
            '{label}' => $editFormLabel,
169
            '{closeButton}' => $this->closeButton,
170
        ]);
171
172
        return $editFormLabel;
173
    }
174
175
    protected function getCreateFormLabel() {
176
        $m  = $this->createFormLabel;
177
178
        $t = $this->translate($m);
179
180
        return $t;
181
    }
182
183
    protected function getEditFormLabel() {
184
        $editFormLabel = $this->editFormLabel;
185
        if (is_callable($editFormLabel)) {
186
            $editFormLabel = $editFormLabel($this->model);
187
        } else {
188
            $editFormLabel = \yii::t('execut.actions', $editFormLabel);
189
        }
190
191
        return $editFormLabel;
192
    }
193
194
    public function getDefaultViewRendererConfig() {
195
        return [
196
            'class' => DetailView::className(),
197
            'uniqueId' => $this->uniqueId,
198
            'heading' => $this->getHeading(),
199
            'action' => $this->getFormAction(),
200
        ];
201
    }
202
203
    protected $_formAction = null;
204
205
    public function setFormAction($action) {
206
        $this->_formAction = $action;
207
208
        return $this;
209
    }
210
211
    protected function getFormAction() {
212
        if ($this->_formAction === null) {
213
            return $this->getUrlParams();
214
        }
215
216
        return $this->_formAction;
217
    }
218
219
    /**
220
     * @param $model
221
     */
222
    protected function redirectAfterSave()
223
    {
224
        if ($this->urlParamsForRedirectAfterSave === false) {
225
            return false;
226
        }
227
228
        $data = $this->actionParams->getData();
229
        $params = $this->getUrlParams();
230
        if (is_callable($this->urlParamsForRedirectAfterSave)) {
231
            $urlParamsForRedirectAfterSave = $this->urlParamsForRedirectAfterSave;
232
            $params = $urlParamsForRedirectAfterSave($params);
233
        } else {
234
            $params = ArrayHelper::merge($this->urlParamsForRedirectAfterSave, $params);
235
            if (!empty($params[1])) {
236
                unset($params[1]);
237
            }
238
239
            if (!empty($data['save'])) {
240
                $params = [
241
                    str_replace('/update', '/index', $this->getUniqueId()),
242
                ];
243
            }
244
        }
245
246
        $result = \yii::$app->response->redirect($params);
247
248
        return $result;
249
    }
250
251
    public function getData() {
252
        $data = parent::getData();
253
        $model = $this->getModel();
254
        if (!$model) {
255
            return $data;
256
        }
257
258
        if (empty($data[$model->formName()])) {
259
            $data[$this->getModel()->formName()] = [];
260
        }
261
262
        foreach ($this->additionalAttributes as $attribute) {
263
            if (!empty($data[$attribute])) {
264
                $data[$this->getModel()->formName()][$attribute] = $data[$attribute];
265
            }
266
        }
267
268
        return $data;
269
    }
270
271
    /**
272
     * @param $model
273
     * @return array
274
     */
275
    protected function getUrlParams(): array
276
    {
277
        $model = $this->model;
278
        $params = [
279
            $this->actionParams->uniqueId,
280
            'id' => $model->primaryKey,
281
        ];
282
283
        foreach ($this->additionalAttributes as $attribute) {
284
            $params[$attribute] = $model->$attribute;
285
        }
286
        return $params;
287
    }
288
289
    /**
290
     * @param $m
291
     * @return string
292
     */
293
    protected function translate($m): string
294
    {
295
        $m = \yii::t('execut.actions', $m);
296
297
        return $m;
298
    }
299
300
    /**
301
     * @return string
302
     */
303
    protected function getTemplateSuccessMessage(): string
304
    {
305
        if ($this->templateSuccessMessage !== null) {
306
            return $this->templateSuccessMessage;
307
        }
308
309
        $template = $this->translate('Record') . ' #{id} ' . $this->translate('is successfully') . ' {operation}';
310
311
        return $template;
312
    }
313
314
    /**
315
     * @param $flash
316
     */
317
    protected function setFlash($flash, $type = 'success'): void
318
    {
319
        if ($session = $this->getSession()) {
320
            $session->addFlash('kv-detail-' . $type, $flash);
321
        }
322
    }
323
324
    /**
325
     * @param $model
326
     * @return string
327
     */
328
    protected function getSuccessMessage($isNewRecord)
329
    {
330
        $model = $this->getModel();
331
        if ($this->templateSuccessMessage !== false) {
332
            if ($isNewRecord) {
333
                $operation = 'created';
334
            } else {
335
                $operation = 'updated';
336
            }
337
338
            $operation = $this->translate($operation);
339
340
            $parts = [
341
                '{id}' => $model->primaryKey,
342
                '{operation}' => $operation,
343
            ];
344
345
            $template = $this->getTemplateSuccessMessage();
346
347
            $successMessage = strtr($template, $parts);
348
349
            return $successMessage;
350
        }
351
    }
352
}