Completed
Push — master ( 6b7664...8cf912 )
by Alexey
05:42
created

DataManager::__construct()   C

Complexity

Conditions 8
Paths 16

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 8
eloc 18
c 3
b 1
f 0
nc 16
nop 2
dl 0
loc 29
rs 5.3846
1
<?php
2
/**
3
 * Data manager
4
 *
5
 * @author Alexey Krupskiy <[email protected]>
6
 * @link http://inji.ru/
7
 * @copyright 2015 Alexey Krupskiy
8
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
9
 */
10
11
namespace Ui;
12
13
class DataManager extends \Object
14
{
15
    public $modelName = '';
16
    public $managerOptions = [];
17
    public $managerName = 'customManager';
18
    public $name = 'Менеджер данных';
19
    public $limit = 30;
20
    public $page = 1;
21
    public $table = null;
22
    public $joins = [];
23
    public $predraw = false;
24
    public $cols = [];
25
    public $managerId = '';
26
27
    /**
28
     * Construct new data manager
29
     * 
30
     * @param string|array $modelNameOrOptions
31
     * @param string $dataManager
0 ignored issues
show
Bug introduced by
There is no parameter named $dataManager. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
32
     * @throws Exception
33
     */
34
    public function __construct($modelNameOrOptions, $managerName = 'manager')
35
    {
36
        $this->managerName = $managerName;
37
38
        if (!is_array($modelNameOrOptions)) {
39
            if (!class_exists($modelNameOrOptions)) {
40
                throw new \Exception("model {$modelNameOrOptions} not exists");
41
            }
42
            $this->modelName = $modelNameOrOptions;
43
            $this->managerOptions = !empty($modelNameOrOptions::$dataManagers[$managerName]) ? $modelNameOrOptions::$dataManagers[$managerName] : [];
44
            if (isset($modelNameOrOptions::$objectName)) {
45
                $this->name = $modelNameOrOptions::$objectName;
46
            } else {
47
                $this->name = $modelNameOrOptions;
48
            }
49
        } else {
50
            $this->managerOptions = $modelNameOrOptions;
51
        }
52
53
        if (!$this->managerOptions || !is_array($this->managerOptions)) {
54
            throw new \Exception('empty DataManager');
55
        }
56
57
        if (!empty($this->managerOptions['name'])) {
58
            $this->name = $this->managerOptions['name'];
59
        }
60
61
        $this->managerId = str_replace('\\', '_', 'dataManager_' . $this->modelName . '_' . $this->managerName . '_' . \Tools::randomString());
62
    }
63
64
    /**
65
     * Get buttons for manager
66
     * 
67
     * @param string $params
68
     * @param object $model
69
     */
70
    public function getButtons($params = [], $model = null)
71
    {
72
        $modelName = $this->modelName;
73
        $formParams = [
74
            'dataManagerParams' => $params,
75
            'formName' => !empty($this->managerOptions['editForm']) ? $this->managerOptions['editForm'] : 'manager'
76
        ];
77
        if ($model) {
78
            $formModelName = get_class($model);
79
            $relations = $formModelName::relations();
80
            $type = !empty($relations[$params['relation']]['type']) ? $relations[$params['relation']]['type'] : 'to';
81
            switch ($type) {
82
                case 'relModel':
83
                    $formParams['preset'] = [
84
                        $formModelName::index() => $model->pk()
85
                    ];
86
                    break;
87
                default:
88
                    $formParams['preset'] = [
89
                        $relations[$params['relation']]['col'] => $model->pk()
90
                    ];
91
            }
92
        }
93
94
        $buttons = [];
95
        if (!empty($this->managerOptions['sortMode'])) {
96
            $buttons[] = [
97
                'class' => 'modeBtn',
98
                'data-mode' => 'sort',
99
                'text' => 'Сортировать',
100
            ];
101
        }
102
        if (!empty($this->managerOptions['filters'])) {
103
            $buttons[] = [
104
                'text' => 'Фильтры',
105
                'onclick' => '  var modal = $("#' . $this->managerId . '_filters");
106
                modal.modal("show");',
107
            ];
108
        }
109
        $buttons[] = [
110
            'text' => 'Добавить элемент',
111
            'onclick' => 'inji.Ui.forms.popUp("' . str_replace('\\', '\\\\', $modelName) . '",' . json_encode($formParams) . ')',
112
        ];
113
114
        return $buttons;
115
    }
116
117
    function getActions($onlyGroupActions = false)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
118
    {
119
        $actions = [
120
            'Open' => ['className' => 'Open'], 'Edit' => ['className' => 'Edit'], 'Delete' => ['className' => 'Delete']
121
        ];
122
        if (isset($this->managerOptions['actions'])) {
123
            $actions = array_merge($actions, $this->managerOptions['actions']);
124
        }
125
        $return = [];
126
        foreach ($actions as $key => $action) {
127
            if ($action === false) {
128
                continue;
129
            }
130
            if (is_array($action)) {
131
                if (!empty($action['access']['groups']) && !in_array(\Users\User::$cur->group_id, $action['access']['groups'])) {
132
                    continue;
133
                }
134
                $return[$key] = $action;
135
            } else {
136
                $key = $action;
137
                $return[$key] = [
138
                    'className' => $action
139
                ];
140
            }
141
            $return[$key]['className'] = strpos($return[$key]['className'], '\\') === false && class_exists('Ui\DataManager\Action\\' . $return[$key]['className']) ? 'Ui\DataManager\Action\\' . $return[$key]['className'] : $return[$key]['className'];
142
            if (!class_exists($return[$key]['className']) || ($onlyGroupActions && !$return[$key]['className']::$groupAction)) {
143
                unset($return[$key]);
144
            }
145
        }
146
        return $return;
147
    }
148
149
    /**
150
     * Get cols for manager
151
     * 
152
     * @return string
153
     */
154
    public function getCols()
155
    {
156
        $actions = $this->getActions();
157
        ob_start();
158
        ?>
159
        <div class="dropdown">
160
          <a id="dLabel" data-target="#" href="" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
161
            <i class="glyphicon glyphicon-cog"></i>
162
            <span class="caret"></span>
163
          </a>
164
165
          <ul class="dropdown-menu" aria-labelledby="dLabel">
166
            <li><a href ='' onclick='inji.Ui.dataManagers.get(this).rowSelection("selectAll");return false;'>Выделить все</a></li>
167
            <li><a href ='' onclick='inji.Ui.dataManagers.get(this).rowSelection("unSelectAll");return false;'>Снять все</a></li>
168
            <li><a href ='' onclick='inji.Ui.dataManagers.get(this).rowSelection("inverse");return false;'>Инвертировать</a></li>
169
            <li role="separator" class="divider"></li>
170
              <?php
171
              foreach ($actions as $action => $actionParams) {
172
                  if (class_exists($actionParams['className']) && $actionParams['className']::$groupAction) {
173
                      echo "<li><a href ='' onclick='inji.Ui.dataManagers.get(this).groupAction(\"" . str_replace('\\', '\\\\', $action) . "\");return false;'>{$actionParams['className']::$name}</a></li>";
174
                  }
175
              }
176
              ?>
177
          </ul>
178
        </div>
179
        <?php
180
        $dropdown = ob_get_contents();
181
        ob_end_clean();
182
183
        $cols = [];
184
        $cols[] = ['label' => $dropdown];
185
        $cols['id'] = ['label' => '№', 'sortable' => true];
186
187
        $modelName = $this->modelName;
188
        foreach ($this->managerOptions['cols'] as $key => $col) {
189
            if (is_array($col)) {
190
                $colName = $key;
191
                $colOptions = $col;
192
            } else {
193
                $colName = $col;
194
                $colOptions = [];
195
            }
196
            $colInfo = [];
197
            if ($modelName) {
198
                $colInfo = $modelName::getColInfo($colName);
199
            }
200
            if (empty($colOptions['label']) && !empty($colInfo['label'])) {
201
                $colOptions['label'] = $colInfo['label'];
202
            } elseif (empty($colOptions['label'])) {
203
                $colOptions['label'] = $colName;
204
            }
205
            $cols[$colName] = $colOptions;
206
        }
207
        return $cols;
208
    }
209
210
    /**
211
     * Get rows for manager
212
     * 
213
     * @param array $params
214
     * @param object $model
215
     * @return type
216
     */
217
    public function getRows($params = [], $model = null)
218
    {
219
        $modelName = $this->modelName;
220
        if (!class_exists($modelName)) {
221
            return [];
222
        }
223 View Code Duplication
        if (!$this->checkAccess()) {
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...
224
            $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->managerName . '"');
225
            return [];
226
        }
227
        $modelName = $this->modelName;
228
        $queryParams = [];
229
        if (empty($params['all'])) {
230
            if (!empty($params['limit'])) {
231
                $this->limit = (int) $params['limit'];
232
            }
233
            if (!empty($params['page'])) {
234
                $this->page = (int) $params['page'];
235
            }
236
            $queryParams['limit'] = $this->limit;
237
            $queryParams['start'] = $this->page * $this->limit - $this->limit;
238
        }
239 View Code Duplication
        if (!empty($params['categoryPath']) && $modelName::$categoryModel) {
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...
240
            $queryParams['where'][] = ['tree_path', $params['categoryPath'] . '%', 'LIKE'];
241
        }
242
        if (!empty($params['appType'])) {
243
            $queryParams['appType'] = $params['appType'];
244
        }
245
        if ($this->joins) {
246
            $queryParams['joins'] = $this->joins;
247
        }
248 View Code Duplication
        if (!empty($this->managerOptions['userGroupFilter'][\Users\User::$cur->group_id]['getRows'])) {
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...
249
            foreach ($this->managerOptions['userGroupFilter'][\Users\User::$cur->group_id]['getRows'] as $colName => $colOptions) {
250
                if (!empty($colOptions['userCol'])) {
251
                    if (strpos($colOptions['userCol'], ':')) {
252
                        $rel = substr($colOptions['userCol'], 0, strpos($colOptions['userCol'], ':'));
253
                        $param = substr($colOptions['userCol'], strpos($colOptions['userCol'], ':') + 1);
254
                        $queryParams['where'][] = [$colName, \Users\User::$cur->$rel->$param];
255
                    }
256
                } elseif (isset($colOptions['value'])) {
257
                    $queryParams['where'][] = [$colName, $colOptions['value'], is_array($colOptions['value']) ? 'IN' : '='];
258
                }
259
            }
260
        }
261
        if (!empty($this->managerOptions['filters'])) {
262
            foreach ($this->managerOptions['filters'] as $col) {
263
                $colInfo = $modelName::getColInfo($col);
264
                switch ($colInfo['colParams']['type']) {
265 View Code Duplication
                    case 'select':
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...
266
                        if (empty($params['filters'][$col]['value'])) {
267
                            continue;
268
                        }
269
                        if (is_array($params['filters'][$col]['value'])) {
270
                            foreach ($params['filters'][$col]['value'] as $key => $value) {
271
                                if ($value === '') {
272
                                    unset($params['filters'][$col]['value'][$key]);
273
                                }
274
                            }
275
                        }
276
                        if (!$params['filters'][$col]['value']) {
277
                            continue;
278
                        }
279
                        $queryParams['where'][] = [$col, $params['filters'][$col]['value'], is_array($params['filters'][$col]['value']) ? 'IN' : '='];
280
                        break;
281
                    case 'bool':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
282
283
                        if (!isset($params['filters'][$col]['value']) || $params['filters'][$col]['value'] === '') {
284
                            continue;
285
                        }
286
                        $queryParams['where'][] = [$col, $params['filters'][$col]['value']];
287
                        break;
288
                    case 'dateTime':
289 View Code Duplication
                    case 'date':
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...
290
                        if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
291
                            continue;
292
                        }
293
                        if (!empty($params['filters'][$col]['min'])) {
294
                            $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
295
                        }
296
                        if (!empty($params['filters'][$col]['max'])) {
297
                            if ($colInfo['colParams']['type'] == 'dateTime' && !strpos($params['filters'][$col]['max'], ' ')) {
298
299
                                $date = $params['filters'][$col]['max'] . ' 23:59:59';
300
                            } else {
301
                                $date = $params['filters'][$col]['max'];
302
                            }
303
                            $queryParams['where'][] = [$col, $date, '<='];
304
                        }
305
                        break;
306 View Code Duplication
                    case 'number':
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...
307
                        if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
308
                            continue;
309
                        }
310
                        if (!empty($params['filters'][$col]['min'])) {
311
                            $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
312
                        }
313
                        if (!empty($params['filters'][$col]['max'])) {
314
                            $queryParams['where'][] = [$col, $params['filters'][$col]['max'], '<='];
315
                        }
316
                        break;
317
                    case 'email':
318
                    case 'text':
319
                    case 'textarea':
320 View Code Duplication
                    case 'html':
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...
321
                        if (empty($params['filters'][$col]['value'])) {
322
                            continue;
323
                        }
324
                        switch ($params['filters'][$col]['compareType']) {
325
                            case 'contains':
326
                                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'] . '%', 'LIKE'];
327
                                break;
328
                            case 'equals':
329
                                $queryParams['where'][] = [$col, $params['filters'][$col]['value']];
330
                                break;
331
                            case 'starts_with':
332
                                $queryParams['where'][] = [$col, $params['filters'][$col]['value'] . '%', 'LIKE'];
333
                                break;
334
                            case 'ends_with':
335
                                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'], 'LIKE'];
336
                                break;
337
                        }
338
                        break;
339
                }
340
            }
341
        }
342
        if (!empty($params['mode']) && $params['mode'] == 'sort') {
343
            $queryParams['order'] = ['weight', 'asc'];
344
        } elseif (!empty($params['sortered']) && !empty($this->managerOptions['sortable'])) {
345
            foreach ($params['sortered'] as $key => $sortType) {
346
                $keys = array_keys($this->managerOptions['cols']);
347
                $colName = '';
348
                if (isset($keys[$key])) {
349
                    if (is_array($this->managerOptions['cols'][$keys[$key]])) {
350
                        $colName = $keys[$key];
351
                    } else {
352
                        $colName = $this->managerOptions['cols'][$keys[$key]];
353
                    }
354
                }
355
                if ($colName && in_array($colName, $this->managerOptions['sortable'])) {
356
                    $sortType = in_array($sortType, ['desc', 'asc']) ? $sortType : 'desc';
357
                    $queryParams['order'][] = [$colName, $sortType];
358
                }
359
            }
360
        }
361
        if ($model && !empty($params['relation'])) {
362
            $relation = $model::getRelation($params['relation']);
363
            $items = $model->$params['relation']($queryParams);
364
        } else {
365
            $relation = false;
366
            $items = $modelName::getList($queryParams);
367
        }
368
        $rows = [];
369
        foreach ($items as $item) {
370
            if ($relation && !empty($relation['relModel'])) {
371
                $item = $relation['relModel']::get([[$item->index(), $item->id], [$model->index(), $model->id]]);
372
            }
373
            $row = [];
374
            $row[] = '<input type ="checkbox" name = "pk[]" value =' . $item->pk() . '>';
375
            $row[] = $item->pk();
376
            foreach ($this->managerOptions['cols'] as $key => $colName) {
377
                if (!empty($params['download'])) {
378
                    $row[] = \Model::getColValue($item, is_array($colName) ? $key : $colName, true, false);
379
                } else {
380
                    $row[] = DataManager::drawCol($item, is_array($colName) ? $key : $colName, $params, $this);
381
                }
382
            }
383
            $row[] = $this->rowButtons($item, $params);
384
            $rows[] = $row;
385
        }
386
        return $rows;
387
    }
388
389
    public static function drawCol($item, $colName, $params = [], $dataManager = null, $originalCol = '', $originalItem = null)
1 ignored issue
show
Coding Style introduced by
drawCol uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
390
    {
391
        $modelName = get_class($item);
392
        if (!class_exists($modelName)) {
393
            return false;
394
        }
395
396
        if (!$originalCol) {
397
            $originalCol = $colName;
398
        }
399
        if (!$originalItem) {
400
            $originalItem = $item;
401
        }
402
403
        $relations = $modelName::relations();
404
        if (strpos($colName, ':') !== false && !empty($relations[substr($colName, 0, strpos($colName, ':'))])) {
405
            $rel = substr($colName, 0, strpos($colName, ':'));
406
            $col = substr($colName, strpos($colName, ':') + 1);
407
            if ($item->$rel) {
408
                return DataManager::drawCol($item->$rel, $col, $params, $dataManager, $originalCol, $originalItem);
409
            } else {
410
                return 'Не указано';
411
            }
412
        }
413
        if (!empty($modelName::$cols[$colName]['relation'])) {
414
            $type = !empty($relations[$modelName::$cols[$colName]['relation']]['type']) ? $relations[$modelName::$cols[$colName]['relation']]['type'] : 'to';
415
            switch ($type) {
416 View Code Duplication
                case 'relModel':
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...
417
                    $managerParams = ['relation' => $modelName::$cols[$colName]['relation']];
418
                    $count = $item->{$modelName::$cols[$colName]['relation']}(array_merge($params, ['count' => 1]));
419
                    $count = $count ? $count : 'Нет';
420
                    return "<a class = 'btn btn-xs btn-primary' onclick = 'inji.Ui.dataManagers.popUp(\"" . str_replace('\\', '\\\\', $modelName) . ":" . $item->pk() . "\"," . json_encode(array_merge($params, $managerParams)) . ")'>{$count}</a>";
421 View Code Duplication
                case 'many':
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...
422
                    $managerParams = ['relation' => $modelName::$cols[$colName]['relation']];
423
                    $count = $item->{$modelName::$cols[$colName]['relation']}(array_merge($params, ['count' => 1]));
424
                    $count = $count ? $count : 'Нет';
425
                    return "<a class = 'btn btn-xs btn-primary' onclick = 'inji.Ui.dataManagers.popUp(\"" . str_replace('\\', '\\\\', $modelName) . ":" . $item->pk() . "\"," . json_encode(array_merge($params, $managerParams)) . ")'>{$count}</a>";
426
                default :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a DEFAULT statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in the default statement.

switch ($expr) {
    default : //wrong
        doSomething();
        break;
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
427
                    if ($item->{$modelName::$cols[$colName]['relation']}) {
428
                        if (\App::$cur->name == 'admin') {
429
                            $href = "<a href ='/admin/" . str_replace('\\', '/view/', $relations[$modelName::$cols[$colName]['relation']]['model']) . "/" . $item->{$modelName::$cols[$colName]['relation']}->pk() . "'>";
430
                            if (!empty($modelName::$cols[$colName]['showCol'])) {
431
                                $href .= $item->{$modelName::$cols[$colName]['relation']}->{$modelName::$cols[$colName]['showCol']};
432
                            } else {
433
434
                                $href .= $item->{$modelName::$cols[$colName]['relation']}->name();
435
                            }
436
                            $href .= '</a>';
437
                            return $href;
438
                        } else {
439
                            return $item->{$modelName::$cols[$colName]['relation']}->name();
440
                        }
441
                    } else {
442
                        return $item->$colName;
443
                    }
444
            }
445
        } else {
446
            if (!empty($modelName::$cols[$colName]['view']['type'])) {
447
                switch ($modelName::$cols[$colName]['view']['type']) {
448
                    case 'widget':
449
                        ob_start();
450
                        \App::$cur->view->widget($modelName::$cols[$colName]['view']['widget'], ['item' => $item, 'colName' => $colName, 'colParams' => $modelName::$cols[$colName]]);
451
                        $content = ob_get_contents();
452
                        ob_end_clean();
453
                        return $content;
454
                    case 'moduleMethod':
455
                        return \App::$cur->{$modelName::$cols[$colName]['view']['module']}->{$modelName::$cols[$colName]['view']['method']}($item, $colName, $modelName::$cols[$colName]);
456
                    case'many':
0 ignored issues
show
Coding Style introduced by
As per coding-style, case should be followed by a single space.

As per the PSR-2 coding standard, there must be a space after the case keyword, instead of the test immediately following it.

switch (true) {
    case!isset($a):  //wrong
        doSomething();
        break;
    case !isset($b):  //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
457
                        $managerParams = ['relation' => $modelName::$cols[$colName]['relation']];
458
                        $count = $item->{$modelName::$cols[$colName]['relation']}(array_merge($params, ['count' => 1]));
459
                        return "<a class = 'btn btn-xs btn-primary' onclick = 'inji.Ui.dataManagers.popUp(\"" . str_replace('\\', '\\\\', $modelName) . ":" . $item->pk() . "\"," . json_encode(array_merge($params, $managerParams)) . ")'>{$count} " . \Tools::getNumEnding($count, ['Элемент', 'Элемента', 'Элементов']) . "</a>";
460
                    default:
461
                        return $item->$colName;
462
                }
463
            } elseif (!empty($modelName::$cols[$colName]['type'])) {
464
                if (\App::$cur->name == 'admin' && $originalCol == 'name' || ( $dataManager && !empty($dataManager->managerOptions['colToView']) && $dataManager->managerOptions['colToView'] == $originalCol)) {
465
                    $formName = $dataManager && !empty($dataManager->managerOptions['editForm']) ? $dataManager->managerOptions['editForm'] : 'manager';
466
                    $redirectUrl = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/admin/' . str_replace('\\', '/', get_class($originalItem));
467
                    return "<a href ='/admin/" . str_replace('\\', '/view/', get_class($originalItem)) . "/{$originalItem->id}?formName={$formName}&redirectUrl={$redirectUrl}'>{$item->$colName}</a>";
468
                } elseif (\App::$cur->name == 'admin' && $colName == 'name') {
469
                    $redirectUrl = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/admin/' . str_replace('\\', '/', get_class($originalItem));
470
                    return "<a href ='/admin/" . str_replace('\\', '/view/', get_class($item)) . "/{$item->id}?redirectUrl={$redirectUrl}'>{$item->$colName}</a>";
471
                } else {
472
                    return \Model::resloveTypeValue($item, $colName);
473
                }
474
            } else {
475
                return $item->$colName;
476
            }
477
        }
478
    }
479
480
    public function rowButtons($item, $params)
481
    {
482
        $modelName = $this->modelName;
483
        if (!class_exists($modelName)) {
484
            return false;
485
        }
486
        ob_start();
487
        $widgetName = !empty($this->managerOptions['rowButtonsWidget']) ? $this->managerOptions['rowButtonsWidget'] : 'Ui\DataManager/rowButtons';
488
        \App::$cur->view->widget($widgetName, [
489
            'dataManager' => $this,
490
            'item' => $item,
491
            'params' => $params
492
        ]);
493
        $buttons = ob_get_contents();
494
        ob_end_clean();
495
        return $buttons;
496
    }
497
498
    public function getPages($params = [], $model = null)
499
    {
500
        $modelName = $this->modelName;
501
        if (!class_exists($modelName)) {
502
            return [];
503
        }
504 View Code Duplication
        if (!$this->checkAccess()) {
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...
505
            $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->managerName . '"');
506
            return [];
507
        }
508
        if (!empty($params['limit'])) {
509
            $this->limit = (int) $params['limit'];
510
        }
511
        if (!empty($params['page'])) {
512
            $this->page = (int) $params['page'];
513
        }
514
        $queryParams = [
515
            'count' => true
516
        ];
517
        $modelName = $this->modelName;
518 View Code Duplication
        if (!empty($params['categoryPath']) && $modelName::$categoryModel) {
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...
519
            $queryParams['where'][] = ['tree_path', $params['categoryPath'] . '%', 'LIKE'];
520
        }
521 View Code Duplication
        if (!empty($this->managerOptions['userGroupFilter'][\Users\User::$cur->group_id]['getRows'])) {
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...
522
            foreach ($this->managerOptions['userGroupFilter'][\Users\User::$cur->group_id]['getRows'] as $colName => $colOptions) {
523
                if (!empty($colOptions['userCol'])) {
524
                    if (strpos($colOptions['userCol'], ':')) {
525
                        $rel = substr($colOptions['userCol'], 0, strpos($colOptions['userCol'], ':'));
526
                        $param = substr($colOptions['userCol'], strpos($colOptions['userCol'], ':') + 1);
527
                        $queryParams['where'][] = [$colName, \Users\User::$cur->$rel->$param];
528
                    }
529
                } elseif (isset($colOptions['value'])) {
530
                    $queryParams['where'][] = [$colName, $colOptions['value'], is_array($colOptions['value']) ? 'IN' : '='];
531
                }
532
            }
533
        }
534
        $modelName = $this->modelName;
535
        if (!empty($this->managerOptions['filters'])) {
536
            foreach ($this->managerOptions['filters'] as $col) {
537
                $colInfo = $modelName::getColInfo($col);
538
                switch ($colInfo['colParams']['type']) {
539 View Code Duplication
                    case 'select':
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...
540
                        if (empty($params['filters'][$col]['value'])) {
541
                            continue;
542
                        }
543
                        if (is_array($params['filters'][$col]['value'])) {
544
                            foreach ($params['filters'][$col]['value'] as $key => $value) {
545
                                if ($value === '') {
546
                                    unset($params['filters'][$col]['value'][$key]);
547
                                }
548
                            }
549
                        }
550
                        if (!$params['filters'][$col]['value']) {
551
                            continue;
552
                        }
553
                        $queryParams['where'][] = [$col, $params['filters'][$col]['value'], is_array($params['filters'][$col]['value']) ? 'IN' : '='];
554
                        break;
555
                    case 'bool':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
556
557
                        if (empty($params['filters'][$col]['value'])) {
558
                            continue;
559
                        }
560
                        $queryParams['where'][] = [$col, '1'];
561
                        break;
562
                    case 'dateTime':
563 View Code Duplication
                    case 'date':
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...
564
                        if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
565
                            continue;
566
                        }
567
                        if (!empty($params['filters'][$col]['min'])) {
568
                            $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
569
                        }
570
                        if (!empty($params['filters'][$col]['max'])) {
571
                            if ($colInfo['colParams']['type'] == 'dateTime' && !strpos($params['filters'][$col]['max'], ' ')) {
572
573
                                $date = $params['filters'][$col]['max'] . ' 23:59:59';
574
                            } else {
575
                                $date = $params['filters'][$col]['max'];
576
                            }
577
                            $queryParams['where'][] = [$col, $date, '<='];
578
                        }
579
                        break;
580 View Code Duplication
                    case 'number':
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...
581
                        if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
582
                            continue;
583
                        }
584
                        if (!empty($params['filters'][$col]['min'])) {
585
                            $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
586
                        }
587
                        if (!empty($params['filters'][$col]['max'])) {
588
                            $queryParams['where'][] = [$col, $params['filters'][$col]['max'], '<='];
589
                        }
590
                        break;
591
                    case 'email':
592
                    case 'text':
593
                    case 'textarea':
594 View Code Duplication
                    case 'html':
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...
595
                        if (empty($params['filters'][$col]['value'])) {
596
                            continue;
597
                        }
598
                        switch ($params['filters'][$col]['compareType']) {
599
                            case 'contains':
600
                                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'] . '%', 'LIKE'];
601
                                break;
602
                            case 'equals':
603
                                $queryParams['where'][] = [$col, $params['filters'][$col]['value']];
604
                                break;
605
                            case 'starts_with':
606
                                $queryParams['where'][] = [$col, $params['filters'][$col]['value'] . '%', 'LIKE'];
607
                                break;
608
                            case 'ends_with':
609
                                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'], 'LIKE'];
610
                                break;
611
                        }
612
                        break;
613
                }
614
            }
615
        }
616
        if ($model && !empty($params['relation'])) {
617
            $count = $model->$params['relation']($queryParams);
618
        } else {
619
            $count = $modelName::getCount($queryParams);
620
        }
621
        $pages = new Pages([
622
            'limit' => $this->limit,
623
            'page' => $this->page,
624
                ], [
625
            'count' => $count,
626
            'dataManager' => $this
627
        ]);
628
        return $pages;
629
    }
630
631
    public function preDraw($params = [], $model = null)
632
    {
633
        $this->predraw = true;
634
635
        $cols = $this->getCols();
636
637
        $this->table = new Table();
638
        $tableCols = [];
639
        foreach ($cols as $colName => $colOptions) {
640
            $tableCols[] = !empty($colOptions['label']) ? $colOptions['label'] : $colName;
641
        }
642
        $tableCols[] = '';
643
        $this->table->class .=' datamanagertable';
644
        $this->table->setCols($tableCols);
645
    }
646
647
    public function draw($params = [], $model = null)
648
    {
649
        if (!$this->predraw) {
650
            $this->preDraw($params, $model);
651
        }
652
        \App::$cur->view->widget('Ui\DataManager/DataManager', [
653
            'dataManager' => $this,
654
            'model' => $model,
655
            'table' => $this->table,
656
            'params' => $params
657
        ]);
658
    }
659
660
    public function drawCategorys()
661
    {
662
        if (!class_exists($this->modelName)) {
663
            return false;
664
        }
665 View Code Duplication
        if (!$this->checkAccess()) {
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...
666
            $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->managerName . '"');
667
            return [];
668
        }
669
        $tree = new Tree();
670
        $tree->ul($this->managerOptions['categorys']['model'], 0, function($category) {
671
            return "<a href='#' onclick='inji.Ui.dataManagers.get(this).switchCategory(this);return false;' data-path ='" . $category->tree_path . ($category->pk() ? $category->pk() . "/" : '') . "'> " . $category->name . "</a> 
672
                                    <a href = '#' onclick = 'inji.Ui.forms.popUp(\"" . str_replace('\\', '\\\\', get_class($category)) . ':' . $category->pk() . "\")' class ='glyphicon glyphicon-edit'></a>&nbsp;    
673
                <a onclick='inji.Ui.dataManagers.get(this).delCategory({$category->pk()});return false;' class ='glyphicon glyphicon-remove'></a>";
674
        });
675
        ?>
676
        <?php
677
    }
678
679
    /**
680
     * Draw error message
681
     * 
682
     * @param string $errorText
683
     */
684
    public function drawError($errorText)
685
    {
686
        echo $errorText;
687
    }
688
689
    /**
690
     * Check access cur user to manager with name in param
691
     * 
692
     * @return boolean
693
     */
694
    public function checkAccess()
695
    {
696
        if (\App::$cur->Access && !\App::$cur->Access->checkAccess($this)) {
697
            return false;
698
        }
699
700 View Code Duplication
        if (!empty($this->managerOptions['options']['access']['apps']) && !in_array(\App::$cur->name, $this->managerOptions['options']['access']['apps'])) {
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...
701
            return false;
702
        }
703 View Code Duplication
        if (!empty($this->managerOptions['options']['access']['groups']) && in_array(\Users\User::$cur->group_id, $this->managerOptions['options']['access']['groups'])) {
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...
704
            return true;
705
        }
706
        if ($this->managerName == 'manager' && !\Users\User::$cur->isAdmin()) {
707
            return false;
708
        }
709
        return true;
710
    }
711
712
}
713