Passed
Push — v5 ( e348bf...8a8f01 )
by Alexey
06:35
created

ActiveForm   F

Complexity

Total Complexity 101

Size/Duplication

Total Lines 343
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 343
rs 1.5789
c 0
b 0
f 0
wmc 101

8 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 32 8
B drawCol() 0 28 6
F checkRequest() 0 114 38
D getOptionsList() 0 69 22
A draw() 0 7 3
C checkAccess() 0 21 13
A drawError() 0 2 1
D getInputs() 0 29 10

How to fix   Complexity   

Complex Class

Complex classes like ActiveForm 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 ActiveForm, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Active form
5
 *
6
 * @author Alexey Krupskiy <[email protected]>
7
 * @link http://inji.ru/
8
 * @copyright 2015 Alexey Krupskiy
9
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
10
 */
11
12
namespace Ui;
13
14
class ActiveForm extends \InjiObject {
0 ignored issues
show
Bug introduced by
The type InjiObject 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
16
    /**
17
     * @var \Model
18
     */
19
    public $model = null;
20
    public $modelName = '';
21
    public $header = "";
22
    public $action = "";
23
    public $form = [];
24
    public $inputs = [];
25
    public $formName = 'noNameForm';
26
    public $requestFormName = '';
27
    public $requestFullFormName = '';
28
    public $parent = null;
29
30
    public function __construct($model, $form = '') {
31
        if (is_array($model)) {
32
            $this->form = $model;
33
            if (is_string($form)) {
34
                $this->formName = $form;
35
            }
36
        } else {
37
            $this->model = $model;
38
            $this->modelName = get_class($model);
39
            if (is_array($form)) {
40
                if (empty($form)) {
41
                    throw new \Exception('empty form');
42
                }
43
                $this->form = $form;
44
            } else {
45
                $this->formName = $form;
46
                $this->form = \App::$cur->ui->getModelForm($this->modelName, $form);
47
                if (empty($this->form)) {
48
                    throw new \Exception('empty form ' . $form);
49
                }
50
                $this->inputs = $this->getInputs();
51
            }
52
        }
53
        $this->requestFormName = "ActiveForm_{$this->formName}";
54
        $modeName = $this->modelName;
55
56
        if (!empty($this->form['name'])) {
57
            $this->header = $this->form['name'];
58
        } elseif (!empty($modeName::$objectName)) {
0 ignored issues
show
Bug introduced by
The property objectName does not exist on string.
Loading history...
59
            $this->header = $modeName::$objectName;
60
        } else {
61
            $this->header = $this->modelName;
62
        }
63
    }
64
65
    public function getInputs() {
66
        $inputs = !empty($this->form['inputs']) ? $this->form['inputs'] : [];
67
        $modelName = $this->modelName;
68
        foreach ($this->form['map'] as $row) {
69
            foreach ($row as $col) {
70
                if (!$col || !empty($inputs[$col])) {
71
                    continue;
72
                }
73
                if (strpos($col, 'form:') === 0) {
74
                    $colPath = explode(':', $col);
75
                    if ($this->model->{$colPath[1]}) {
76
                        $inputs[$col] = new ActiveForm($this->model->{$colPath[1]}, $colPath[2]);
77
                    } else {
78
                        $relOptions = $modelName::getRelation($colPath[1]);
79
                        if (!isset($this->model->_params[$modelName::index()])) {
80
                            $this->model->_params[$modelName::index()] = 0;
81
                        }
82
                        $relOptions['model']::fixPrefix($relOptions['col']);
83
                        $inputs[$col] = new ActiveForm(new $relOptions['model'](), $colPath[2]);
84
                    }
85
                    $inputs[$col]->parent = $this;
86
87
                    $inputs[$col]->parent = $this;
88
                } elseif (!empty($modelName::$cols[$col])) {
0 ignored issues
show
Bug introduced by
The property cols does not exist on string.
Loading history...
89
                    $inputs[$col] = $modelName::$cols[$col];
90
                }
91
            }
92
        }
93
        return $inputs;
94
    }
95
96
    public function checkRequest($params = [], $ajax = false) {
97
        if (!$this->checkAccess()) {
98
            $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->formName . '"');
99
            return [];
100
        }
101
        $successId = 0;
102
        $modelName = $this->model;
103
        if (!empty($_POST[$this->requestFormName][$this->modelName]) || !empty($_FILES[$this->requestFormName]['tmp_name'][$this->modelName])) {
104
            $request = !empty($_POST[$this->requestFormName][$this->modelName]) ? $_POST[$this->requestFormName][$this->modelName] : [];
105
            if ($this->model) {
106
                if (!empty($this->form['handler']) && empty($_GET['notSave'])) {
107
108
                    $modelName::{$this->form['handler']}($request);
109
                    $text = 'Новый элемент был успешно добавлен';
110
                    \Msg::add($text, 'success');
0 ignored issues
show
Bug introduced by
The type Msg 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...
111
                    \Msg::show();
112
                } else {
113
                    $presets = !empty($this->form['preset']) ? $this->form['preset'] : [];
114
                    if (!empty($this->form['userGroupPreset'][\Users\User::$cur->group_id])) {
115
                        $presets = array_merge($presets, $this->form['userGroupPreset'][\Users\User::$cur->group_id]);
116
                    }
117
                    $afterSave = [];
118
                    $error = false;
119
                    foreach ($this->inputs as $col => $param) {
120
                        if (!empty($presets[$col])) {
121
                            continue;
122
                        }
123
                        if (is_object($param)) {
124
                            $afterSave[$col] = $param;
125
                            continue;
126
                        }
127
                        if (!empty($this->form['userGroupReadonly'][\Users\User::$cur->group_id]) && in_array($col, $this->form['userGroupReadonly'][\Users\User::$cur->group_id])) {
128
                            continue;
129
                        }
130
                        $type = ucfirst($param['type']);
131
                        if ($type == 'DynamicType') {
132
                            switch ($param['typeSource']) {
133
                                case 'selfMethod':
134
                                    $type = $this->model->{$param['selfMethod']}();
135
                                    if (is_array($type)) {
136
                                        $param = $type;
137
                                        $type = $type['type'];
138
                                    }
139
                                    break;
140
                            }
141
                        }
142
                        $inputClassName = '\Ui\ActiveForm\Input\\' . ucfirst($type);
143
                        /** @var \Ui\ActiveForm\Input $input */
144
                        $input = new $inputClassName();
145
                        $input->activeForm = $this;
146
                        $input->activeFormParams = $params;
147
                        $input->modelName = $this->modelName;
148
                        $input->colName = $col;
149
                        $input->colParams = $param;
150
                        try {
151
                            $input->validate($request);
152
                            $input->parseRequest($request);
153
                        } catch (\Exception $exc) {
154
                            \Msg::add($exc->getMessage(), 'danger');
155
                            $error = true;
156
                        }
157
                    }
158
                    if (!$error && empty($_GET['notSave'])) {
159
                        foreach ($presets as $col => $preset) {
160
                            if (!empty($preset['value'])) {
161
                                $this->model->$col = $preset['value'];
162
                            } elseif (!empty($preset['userCol'])) {
163
                                if (strpos($preset['userCol'], ':')) {
164
                                    $rel = substr($preset['userCol'], 0, strpos($preset['userCol'], ':'));
165
                                    $param = substr($preset['userCol'], strpos($preset['userCol'], ':') + 1);
166
                                    $this->model->$col = \Users\User::$cur->$rel->$param;
167
                                } else {
168
                                    $this->model->$col = \Users\User::$cur->{$preset['userCol']};
169
                                }
170
                            }
171
                        }
172
                        if (!$this->parent) {
173
                            if (!empty($this->form['successText'])) {
174
                                $text = $this->form['successText'];
175
                            } else {
176
                                $text = $this->model->pk() ? 'Изменения были успешно сохранены' : 'Новый элемент был успешно добавлен';
177
                            }
178
                            \Msg::add($text, 'success');
179
                        }
180
181
                        $this->model->save(!empty($params['dataManagerParams']) ? $params['dataManagerParams'] : []);
182
                        foreach ($afterSave as $col => $form) {
183
                            if (strpos($col, 'form:') === 0) {
184
                                $colPath = explode(':', $col);
185
                                if (!$this->model->{$colPath[1]}) {
186
                                    $relOptions = $modelName::getRelation($colPath[1]);
187
                                    if (!isset($this->model->_params[$modelName::index()])) {
188
                                        $this->model->_params[$modelName::index()] = 0;
189
                                    }
190
                                    $relOptions['model']::fixPrefix($relOptions['col']);
191
                                    $form->model->{$relOptions['col']} = $this->model->_params[$modelName::index()];
192
                                }
193
                            }
194
                            $form->checkRequest();
195
                        }
196
                        if ($ajax) {
197
                            \Msg::show();
198
                        } elseif (!empty($_GET['redirectUrl'])) {
199
                            \Tools::redirect($_GET['redirectUrl'] . (!empty($_GET['dataManagerHash']) ? '#' . $_GET['dataManagerHash'] : ''));
0 ignored issues
show
Bug introduced by
The type Tools 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...
200
                        }
201
                        $successId = $this->model->pk();
202
                    }
203
                }
204
            }
205
            if (!is_array($params) && is_callable($params)) {
206
                $params($request);
207
            }
208
        }
209
        return $successId;
210
    }
211
212
    public function draw($params = [], $ajax = false) {
213
        if (!$this->checkAccess()) {
214
            $this->drawError('you not have access to "' . $this->modelName . '" form with name: "' . $this->formName . '"');
215
            return [];
216
        }
217
        $form = new Form(!empty($this->form['formOptions']) ? $this->form['formOptions'] : []);
218
        \App::$cur->view->widget('Ui\ActiveForm', ['form' => $form, 'activeForm' => $this, 'ajax' => $ajax, 'params' => $params]);
219
    }
220
221
    public function drawCol($colName, $options, $form, $params = []) {
222
        if (is_object($options)) {
223
            $options->draw();
224
        } else {
225
            $type = ucfirst($options['type']);
226
            if ($type == 'DynamicType') {
227
                switch ($options['typeSource']) {
228
                    case 'selfMethod':
229
                        $type = $this->model->{$options['selfMethod']}();
230
                        if (is_array($type)) {
231
                            $options = $type;
232
                            $type = $type['type'];
233
                        }
234
                        break;
235
                }
236
            }
237
            $inputClassName = '\Ui\ActiveForm\Input\\' . ucfirst($type);
238
            $input = new $inputClassName();
239
            $input->form = $form;
240
            $input->activeForm = $this;
241
            $input->activeFormParams = $params;
242
            $input->modelName = $this->modelName;
243
            $input->colName = $colName;
244
            $input->colParams = $options;
245
            $input->options = !empty($options['options']) ? $options['options'] : [];
246
            $input->draw();
247
        }
248
        return true;
249
    }
250
251
    public static function getOptionsList($inputParams, $params = [], $modelName = '', $aditionalInputNamePrefix = 'aditional', $options = [],$model=false) {
252
        $values = [];
253
        switch ($inputParams['source']) {
254
            case 'model':
255
                $values = $inputParams['model']::getList(['forSelect' => true]);
256
                break;
257
            case 'array':
258
                $values = $inputParams['sourceArray'];
259
                break;
260
            case 'method':
261
                if (!empty($inputParams['params'])) {
262
                    $values = call_user_func_array([\App::$cur->{$inputParams['module']}, $inputParams['method']], $inputParams['params']+[$model]);
263
                } else {
264
                    $values = \App::$cur->{$inputParams['module']}->{$inputParams['method']}($model);
265
                }
266
                break;
267
            case 'relation':
268
                if (!$modelName) {
269
                    return [];
270
                }
271
                $relation = $modelName::getRelation($inputParams['relation']);
272
                if (!empty($params['dataManagerParams']['appType'])) {
273
                    $options['appType'] = $params['dataManagerParams']['appType'];
274
                }
275
                $items = [];
276
                if (class_exists($relation['model'])) {
277
                    $filters = $relation['model']::managerFilters();
278
                    if (!empty($filters['getRows']['where'])) {
279
                        $options['where'][] = $filters['getRows']['where'];
280
                    }
281
                    if (!empty($relation['where'])) {
282
                        $options['where'][] = $relation['where'];
283
                    }
284
                    if (!empty($relation['order'])) {
285
                        $options['order'] = $relation['order'];
286
                    }
287
                    if (!empty($inputParams['itemName'])) {
288
                        $options['itemName'] = $inputParams['itemName'];
289
                    }
290
                    $items = $relation['model']::getList($options);
291
                }
292
                if (!empty($params['noEmptyValue'])) {
293
                    $values = [];
294
                } else {
295
                    $values = [0 => 'Не задано'];
296
                }
297
                foreach ($items as $key => $item) {
298
                    if (!empty($inputParams['showCol'])) {
299
                        if (is_array($inputParams['showCol'])) {
300
                            switch ($inputParams['showCol']['type']) {
301
                                case 'staticMethod':
302
                                    $values[$key] = $inputParams['showCol']['class']::{$inputParams['showCol']['method']}($item);
303
                                    break;
304
                            }
305
                        } else {
306
                            $values[$key] = $item->{$inputParams['showCol']};
307
                        }
308
                    } else {
309
                        $values[$key] = $item->name();
310
                    }
311
                }
312
                break;
313
        }
314
        foreach ($values as $key => $value) {
315
            if (is_array($value) && !empty($value['input']) && empty($value['input']['noprefix'])) {
316
                $values[$key]['input']['name'] = $aditionalInputNamePrefix . "[{$value['input']['name']}]";
317
            }
318
        }
319
        return $values;
320
    }
321
322
    /**
323
     * Draw error message
324
     *
325
     * @param string $errorText
326
     */
327
    public function drawError($errorText) {
328
        echo $errorText;
329
    }
330
331
    /**
332
     * Check access cur user to form with name in param and $model
333
     *
334
     * @return boolean
335
     */
336
    public function checkAccess() {
337
        if (empty($this->form)) {
338
            $this->drawError('"' . $this->modelName . '" form with name: "' . $this->formName . '" not found');
339
            return false;
340
        }
341
        if (\App::$cur->Access && !\App::$cur->Access->checkAccess($this)) {
342
            return false;
343
        }
344
        if (!empty($this->form['options']['access']['apps']) && !in_array(\App::$cur->name, $this->form['options']['access']['apps'])) {
345
            return false;
346
        }
347
        if (!empty($this->form['options']['access']['groups']) && in_array(\Users\User::$cur->group_id, $this->form['options']['access']['groups'])) {
348
            return true;
349
        }
350
        if ($this->model && !empty($this->form['options']['access']['self']) && \Users\User::$cur->id == $this->model->user_id) {
351
            return true;
352
        }
353
        if ($this->formName == 'manager' && !\Users\User::$cur->isAdmin()) {
354
            return false;
355
        }
356
        return true;
357
    }
358
}
359