ActiveForm::checkAccess()   B
last analyzed

Complexity

Conditions 12
Paths 6

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 11
nc 6
nop 0
dl 0
loc 17
rs 7.4259
c 0
b 0
f 0

How to fix   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
 * 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 Inji\Ui;
13
14
use Inji\App;
15
use Inji\Model\Builder;
16
17
class ActiveForm extends \Inji\InjiObject {
18
19
    /**
20
     * @var \Inji\Model
21
     */
22
    public $model = null;
23
    public $modelName = '';
24
    public $label = null;
25
    public $action = "";
26
    public $form = [];
27
    public $inputs = [];
28
    public $name = 'manager';
29
    public $requestFormName = '';
30
    public $requestFullFormName = '';
31
    public $parent = null;
32
    public $connection = 'default';
33
    public $dbOptions = [];
34
35
    public function __construct() {
36
        $this->requestFormName = 'ActiveForm_' . str_replace('\\', '_', $this->modelName);
37
    }
38
39
    /**
40
     * @param $modelName
41
     * @param $formName
42
     * @return static
43
     */
44
    public static function forModel($modelName, $formName = 'manager') {
45
        if ($formName !== 'manager') {
46
            $className = $modelName . ucfirst($formName) . 'ActiveForm';
47
        } else {
48
            $className = $modelName . 'ActiveForm';
49
        }
50
        return new $className();
51
    }
52
53
    public function modelBuilderFromParams($params = []) {
54
        /**
55
         * @var Builder
56
         */
57
        $builder = $this->modelName::connection($this->connection)->setDbOptions($this->dbOptions);
58
        return $builder;
59
    }
60
61
    public function loadModelById($id, $options = []) {
62
        $builder = $this->modelBuilderFromParams($options);
63
        $builder->where($this->modelName::index(), $id);
64
        $this->model = $builder->get();
65
    }
66
67
    public function setModel($model) {
68
        $this->model = $model;
69
    }
70
71
    public function emptyModel() {
72
        $this->model = $this->modelName::create();
73
        $this->model->connectionName = $this->connection;
74
        $this->model->dbOptions = $this->dbOptions;
75
    }
76
77
    public function getInputs() {
78
        $inputs = !empty($this->form['inputs']) ? $this->form['inputs'] : [];
79
        $modelName = $this->modelName;
80
        foreach ($this->map as $row) {
81
            foreach ($row as $col) {
82
                if (!$col || !empty($inputs[$col])) {
83
                    continue;
84
                }
85
                if (strpos($col, 'form:') === 0) {
86
                    $colPath = explode(':', $col);
87
                    if ($this->model->{$colPath[1]}) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
88
                        //$inputs[$col] = new ActiveForm($this->model->{$colPath[1]}, $colPath[2]);
0 ignored issues
show
Unused Code Comprehensibility introduced by
76% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
89
                    } else {
90
                        $relOptions = $modelName::getRelation($colPath[1]);
91
                        if (!isset($this->model->_params[$modelName::index()])) {
92
                            $this->model->_params[$modelName::index()] = 0;
93
                        }
94
                        $relOptions['model']::fixPrefix($relOptions['col']);
95
                        //$inputs[$col] = new ActiveForm(new $relOptions['model'](), $colPath[2]);
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
96
                    }
97
                    $inputs[$col]->parent = $this;
98
99
                    $inputs[$col]->parent = $this;
100
                } elseif (!empty($modelName::$cols[$col])) {
0 ignored issues
show
Bug introduced by
The property cols does not exist on string.
Loading history...
101
                    $inputs[$col] = $modelName::$cols[$col];
102
                }
103
            }
104
        }
105
        return $inputs;
106
    }
107
108
    public function checkRequest($params = [], $ajax = false) {
109
        if (!$this->checkAccess()) {
110
            $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->formName . '"');
0 ignored issues
show
Bug Best Practice introduced by
The property formName does not exist on Inji\Ui\ActiveForm. Did you maybe forget to declare it?
Loading history...
111
            return [];
112
        }
113
        $successId = 0;
114
        $modelName = $this->model;
115
        if (!empty($_POST[$this->requestFormName][$this->modelName]) || !empty($_FILES[$this->requestFormName]['tmp_name'][$this->modelName])) {
116
            $request = !empty($_POST[$this->requestFormName][$this->modelName]) ? $_POST[$this->requestFormName][$this->modelName] : [];
117
            if ($this->model) {
118
                if (!empty($this->form['handler']) && empty($_GET['notSave'])) {
119
120
                    $modelName::{$this->form['handler']}($request);
121
                    $text = 'Новый элемент был успешно добавлен';
122
                    \Inji\Msg::add($text, 'success');
123
                    \Inji\Msg::show();
124
                } else {
125
                    $presets = !empty($this->form['preset']) ? $this->form['preset'] : [];
126
                    if (!empty($this->form['userGroupPreset'][\Inji\Users\User::$cur->group_id])) {
127
                        $presets = array_merge($presets, $this->form['userGroupPreset'][\Inji\Users\User::$cur->group_id]);
128
                    }
129
                    $afterSave = [];
130
                    $error = false;
131
                    foreach ($this->getInputs() as $col => $param) {
132
                        if (!empty($presets[$col])) {
133
                            continue;
134
                        }
135
                        if (is_object($param)) {
136
                            $afterSave[$col] = $param;
137
                            continue;
138
                        }
139
                        if (!empty($this->form['userGroupReadonly'][\Inji\Users\User::$cur->group_id]) && in_array($col, $this->form['userGroupReadonly'][\Inji\Users\User::$cur->group_id])) {
140
                            continue;
141
                        }
142
                        $type = $param['type'];
143
                        if ($type == 'DynamicType') {
144
                            switch ($param['typeSource']) {
145
                                case 'selfMethod':
146
                                    $type = $this->model->{$param['selfMethod']}();
147
                                    if (is_array($type)) {
148
                                        $param = $type;
149
                                        $type = $type['type'];
150
                                    }
151
                                    break;
152
                            }
153
                        }
154
                        if ($type == 'bool') {
155
                            $type = 'checkbox';
156
                        }
157
                        $inputClassName = 'Inji\Ui\ActiveForm\Input\\' . ucfirst($type);
158
                        /** @var \Inji\Ui\ActiveForm\Input $input */
159
                        $input = new $inputClassName();
160
                        $input->activeForm = $this;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this of type Inji\Ui\ActiveForm is incompatible with the declared type Ui\ActiveForm of property $activeForm.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
161
                        $input->activeFormParams = $params;
162
                        $input->modelName = $this->modelName;
163
                        $input->colName = $col;
164
                        $input->colParams = $param;
165
                        try {
166
                            $input->validate($request);
167
                            $input->parseRequest($request);
168
                        } catch (\Exception $exc) {
169
                            \Inji\Msg::add($exc->getMessage(), 'danger');
170
                            $error = true;
171
                        }
172
                    }
173
                    if (!$error && empty($_GET['notSave'])) {
174
                        foreach ($presets as $col => $preset) {
175
                            if (!empty($preset['value'])) {
176
                                $this->model->$col = $preset['value'];
177
                            } elseif (!empty($preset['userCol'])) {
178
                                if (strpos($preset['userCol'], ':')) {
179
                                    $rel = substr($preset['userCol'], 0, strpos($preset['userCol'], ':'));
180
                                    $param = substr($preset['userCol'], strpos($preset['userCol'], ':') + 1);
181
                                    $this->model->$col = \Inji\Users\User::$cur->$rel->$param;
182
                                } else {
183
                                    $this->model->$col = \Inji\Users\User::$cur->{$preset['userCol']};
184
                                }
185
                            }
186
                        }
187
                        if (!$this->parent) {
188
                            if (!empty($this->form['successText'])) {
189
                                $text = $this->form['successText'];
190
                            } else {
191
                                $text = $this->model->pk() ? 'Изменения были успешно сохранены' : 'Новый элемент был успешно добавлен';
192
                            }
193
                            \Inji\Msg::add($text, 'success');
194
                        }
195
                        $this->model->save(!empty($params['dataManagerParams']) ? $params['dataManagerParams'] : []);
196
                        foreach ($afterSave as $col => $form) {
197
                            if (strpos($col, 'form:') === 0) {
198
                                $colPath = explode(':', $col);
199
                                if (!$this->model->{$colPath[1]}) {
200
                                    $relOptions = $modelName::getRelation($colPath[1]);
201
                                    if (!isset($this->model->_params[$modelName::index()])) {
202
                                        $this->model->_params[$modelName::index()] = 0;
203
                                    }
204
                                    $relOptions['model']::fixPrefix($relOptions['col']);
205
                                    $form->model->{$relOptions['col']} = $this->model->_params[$modelName::index()];
206
                                }
207
                            }
208
                            $form->checkRequest();
209
                        }
210
                        if ($ajax) {
211
                            \Inji\Msg::show();
212
                        } elseif (!empty($_GET['redirectUrl'])) {
213
                            \Inji\Tools::redirect($_GET['redirectUrl'] . (!empty($_GET['dataManagerHash']) ? '#' . $_GET['dataManagerHash'] : ''));
214
                        }
215
                        $successId = $this->model->pk();
216
                    }
217
                }
218
            }
219
            if (!is_array($params) && is_callable($params)) {
220
                $params($request);
221
            }
222
        }
223
        return $successId;
224
    }
225
226
    public function draw($params = [], $ajax = false) {
227
        if (!$this->checkAccess()) {
228
            $this->drawError('you not have access to "' . $this->modelName . '" form with name: "' . $this->formName . '"');
0 ignored issues
show
Bug Best Practice introduced by
The property formName does not exist on Inji\Ui\ActiveForm. Did you maybe forget to declare it?
Loading history...
229
            return [];
230
        }
231
        $form = new Form(!empty($this->form['formOptions']) ? $this->form['formOptions'] : []);
232
        App::$cur->view->widget('Ui\ActiveForm', ['form' => $form, 'activeForm' => $this, 'ajax' => $ajax, 'params' => $params]);
0 ignored issues
show
Bug Best Practice introduced by
The property view does not exist on Inji\App. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method widget() does not exist on Inji\Module. It seems like you code against a sub-type of Inji\Module such as Inji\View or Inji\Db. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

232
        App::$cur->view->/** @scrutinizer ignore-call */ 
233
                         widget('Ui\ActiveForm', ['form' => $form, 'activeForm' => $this, 'ajax' => $ajax, 'params' => $params]);
Loading history...
Bug introduced by
The method widget() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

232
        App::$cur->view->/** @scrutinizer ignore-call */ 
233
                         widget('Ui\ActiveForm', ['form' => $form, 'activeForm' => $this, 'ajax' => $ajax, 'params' => $params]);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
233
    }
234
235
    public function drawCol($colName, $options, $form, $params = []) {
236
        if (is_object($options)) {
237
            $options->draw();
238
        } else {
239
            $type = $options['type'];
240
            if ($type == 'DynamicType') {
241
                switch ($options['typeSource']) {
242
                    case 'selfMethod':
243
                        $type = $this->model->{$options['selfMethod']}();
244
                        if (is_array($type)) {
245
                            $options = $type;
246
                            $type = $type['type'];
247
                        }
248
                        break;
249
                }
250
            }
251
            if ($type == 'bool') {
252
                $type = 'checkbox';
253
            }
254
            $inputClassName = '\Inji\Ui\ActiveForm\Input\\' . ucfirst($type);
255
            $input = new $inputClassName();
256
            $input->form = $form;
257
            $input->activeForm = $this;
258
            $input->activeFormParams = $params;
259
            $input->modelName = $this->modelName;
260
            $input->colName = $colName;
261
            $input->colParams = $options;
262
            $input->options = !empty($options['options']) ? $options['options'] : [];
263
            $input->draw();
264
        }
265
        return true;
266
    }
267
268
    public static function getOptionsList($inputParams, $params = [], $modelName = '', $aditionalInputNamePrefix = 'aditional', $options = [], $model = false) {
269
        $values = [];
270
        switch ($inputParams['source']) {
271
            case 'model':
272
                $values = $inputParams['model']::getList(['forSelect' => true]);
273
                break;
274
            case 'array':
275
                $values = $inputParams['sourceArray'];
276
                break;
277
            case 'method':
278
                if (!empty($inputParams['params'])) {
279
                    $values = call_user_func_array([\App::$cur->{$inputParams['module']}, $inputParams['method']], $inputParams['params'] + [$model]);
280
                } else {
281
                    $values = \App::$cur->{$inputParams['module']}->{$inputParams['method']}($model);
282
                }
283
                break;
284
            case 'relation':
285
                if (!$modelName) {
286
                    return [];
287
                }
288
                $relation = $modelName::getRelation($inputParams['relation']);
289
                if (!empty($params['dataManagerParams']['appType'])) {
290
                    $options['appType'] = $params['dataManagerParams']['appType'];
291
                }
292
                $items = [];
293
                if (class_exists($relation['model'])) {
294
                    $filters = $relation['model']::managerFilters();
295
                    if (!empty($filters['getRows']['where'])) {
296
                        $options['where'][] = $filters['getRows']['where'];
297
                    }
298
                    if (!empty($relation['where'])) {
299
                        $options['where'][] = $relation['where'];
300
                    }
301
                    if (!empty($relation['order'])) {
302
                        $options['order'] = $relation['order'];
303
                    }
304
                    if (!empty($inputParams['itemName'])) {
305
                        $options['itemName'] = $inputParams['itemName'];
306
                    }
307
                    $items = $relation['model']::getList($options);
308
                }
309
                if (!empty($params['noEmptyValue'])) {
310
                    $values = [];
311
                } else {
312
                    $values = [0 => 'Не задано'];
313
                }
314
                foreach ($items as $key => $item) {
315
                    if (!empty($inputParams['showCol'])) {
316
                        if (is_array($inputParams['showCol'])) {
317
                            switch ($inputParams['showCol']['type']) {
318
                                case 'staticMethod':
319
                                    $values[$key] = $inputParams['showCol']['class']::{$inputParams['showCol']['method']}($item);
320
                                    break;
321
                            }
322
                        } else {
323
                            $values[$key] = $item->{$inputParams['showCol']};
324
                        }
325
                    } else {
326
                        $values[$key] = $item->name();
327
                    }
328
                }
329
                break;
330
        }
331
        foreach ($values as $key => $value) {
332
            if (is_array($value) && !empty($value['input']) && empty($value['input']['noprefix'])) {
333
                $values[$key]['input']['name'] = $aditionalInputNamePrefix . "[{$value['input']['name']}]";
334
            }
335
        }
336
        return $values;
337
    }
338
339
    /**
340
     * Draw error message
341
     *
342
     * @param string $errorText
343
     */
344
    public function drawError($errorText) {
345
        echo $errorText;
346
    }
347
348
    /**
349
     * Check access cur user to form with name in param and $model
350
     *
351
     * @return boolean
352
     */
353
    public function checkAccess() {
354
        if (\Inji\App::$cur->Access && !\Inji\App::$cur->Access->checkAccess($this)) {
0 ignored issues
show
Bug Best Practice introduced by
The property Access does not exist on Inji\App. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method checkAccess() does not exist on Inji\Module. It seems like you code against a sub-type of Inji\Module such as Inji\Access or Inji\Db. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

354
        if (\Inji\App::$cur->Access && !\Inji\App::$cur->Access->/** @scrutinizer ignore-call */ checkAccess($this)) {
Loading history...
355
            return false;
356
        }
357
        if (!empty($this->form['options']['access']['apps']) && !in_array(\Inji\App::$cur->name, $this->form['options']['access']['apps'])) {
358
            return false;
359
        }
360
        if (!empty($this->form['options']['access']['groups']) && in_array(\Inji\Users\User::$cur->group_id, $this->form['options']['access']['groups'])) {
361
            return true;
362
        }
363
        if ($this->model && !empty($this->form['options']['access']['self']) && \Inji\Users\User::$cur->id == $this->model->user_id) {
0 ignored issues
show
Bug Best Practice introduced by
The property user_id does not exist on Inji\Model. Since you implemented __get, consider adding a @property annotation.
Loading history...
364
            return true;
365
        }
366
        if ($this->formName == 'manager' && !\Inji\Users\User::$cur->isAdmin()) {
0 ignored issues
show
Bug Best Practice introduced by
The property formName does not exist on Inji\Ui\ActiveForm. Did you maybe forget to declare it?
Loading history...
367
            return false;
368
        }
369
        return true;
370
    }
371
}
372