Completed
Push — master ( 7855c2...b6f450 )
by Alexey
07:32
created

DataManager::getButtons()   D

Complexity

Conditions 10
Paths 320

Size

Total Lines 60
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 40
nc 320
nop 2
dl 0
loc 60
rs 4.8
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * 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 $managerName
32
   * @throws Exception
33
   */
34
  public function __construct($modelNameOrOptions, $managerName = 'manager') {
35
    $this->managerName = $managerName;
36
37
    if (!is_array($modelNameOrOptions)) {
38
      if (!class_exists($modelNameOrOptions)) {
39
        throw new \Exception("model {$modelNameOrOptions} not exists");
40
      }
41
      $this->modelName = $modelNameOrOptions;
42
      $this->managerOptions = !empty($modelNameOrOptions::$dataManagers[$managerName]) ? $modelNameOrOptions::$dataManagers[$managerName] : [];
43
      if (isset($modelNameOrOptions::$objectName)) {
44
        $this->name = $modelNameOrOptions::$objectName;
45
      } else {
46
        $this->name = $modelNameOrOptions;
47
      }
48
    } else {
49
      $this->managerOptions = $modelNameOrOptions;
50
    }
51
52
    if (!$this->managerOptions || !is_array($this->managerOptions)) {
53
      throw new \Exception('empty DataManager');
54
    }
55
56
    if (!empty($this->managerOptions['name'])) {
57
      $this->name = $this->managerOptions['name'];
58
    }
59
60
    $this->managerId = str_replace('\\', '_', 'dataManager_' . $this->modelName . '_' . $this->managerName . '_' . \Tools::randomString());
61
  }
62
63
  /**
64
   * Get buttons for manager
65
   * 
66
   * @param string $params
67
   * @param object $model
68
   */
69
  public function getButtons($params = [], $model = null) {
70
    $modelName = $this->modelName;
71
72
73
74
    $formParams = [
75
        'dataManagerParams' => $params,
76
        'formName' => !empty($this->managerOptions['editForm']) ? $this->managerOptions['editForm'] : 'manager'
77
    ];
78
    if ($model) {
79
      $formModelName = get_class($model);
80
      $relations = $formModelName::relations();
81
      $type = !empty($relations[$params['relation']]['type']) ? $relations[$params['relation']]['type'] : 'to';
82
      switch ($type) {
83
        case 'relModel':
84
          $formParams['preset'] = [
85
              $formModelName::index() => $model->pk()
86
          ];
87
          break;
88
        default:
89
          $formParams['preset'] = [
90
              $relations[$params['relation']]['col'] => $model->pk()
91
          ];
92
      }
93
    }
94
95
    $buttons = [];
96
    if (!empty($this->managerOptions['sortMode'])) {
97
      $buttons[] = [
98
          'class' => 'modeBtn',
99
          'data-mode' => 'sort',
100
          'text' => 'Сортировать',
101
      ];
102
    }
103
    if (!empty($this->managerOptions['filters'])) {
104
      $buttons[] = [
105
          'text' => 'Фильтры',
106
          'onclick' => '  var modal = $("#' . $this->managerId . '_filters");
107
                modal.modal("show");',
108
      ];
109
    }
110
    if (!empty($modelName::$forms['simpleItem'])) {
111
      $formParams['formName'] = 'simpleItem';
112
      $buttons[] = [
113
          'text' => '<i class = "glyphicon glyphicon-send"></i> Быстрое создание',
114
          'onclick' => 'inji.Ui.dataManagers.get(this).newItem("' . str_replace('\\', '\\\\', $modelName) . '",' . json_encode($formParams) . ');',
115
      ];
116
    }
117
    $formParams['formName'] = !empty($this->managerOptions['editForm']) ? $this->managerOptions['editForm'] : 'manager';
118
    $name = 'Элемент';
119
    if ($modelName::$objectName) {
120
      $name = $modelName::$objectName;
121
    }
122
    $buttons[] = [
123
        'text' => 'Создать ' . $name,
124
        'onclick' => 'inji.Ui.dataManagers.get(this).newItem("' . str_replace('\\', '\\\\', $modelName) . '",' . json_encode($formParams) . ');',
125
    ];
126
127
    return $buttons;
128
  }
129
130
  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...
131
    $actions = [
132
        'Open' => ['className' => 'Open'], 'Edit' => ['className' => 'Edit'], 'Delete' => ['className' => 'Delete']
133
    ];
134
    if (isset($this->managerOptions['actions'])) {
135
      $actions = array_merge($actions, $this->managerOptions['actions']);
136
    }
137
    $return = [];
138
    foreach ($actions as $key => $action) {
139
      if ($action === false) {
140
        continue;
141
      }
142
      if (is_array($action)) {
143
        if (!empty($action['access']['groups']) && !in_array(\Users\User::$cur->group_id, $action['access']['groups'])) {
144
          continue;
145
        }
146
        $return[$key] = $action;
147
      } else {
148
        $key = $action;
149
        $return[$key] = [
150
            'className' => $action
151
        ];
152
      }
153
      $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'];
154
      if (!class_exists($return[$key]['className']) || ($onlyGroupActions && !$return[$key]['className']::$groupAction)) {
155
        unset($return[$key]);
156
      }
157
    }
158
    return $return;
159
  }
160
161
  /**
162
   * Get cols for manager
163
   * 
164
   * @return string
165
   */
166
  public function getCols() {
167
    $actions = $this->getActions();
168
    ob_start();
169
    ?>
170
    <div class="dropdown">
171
      <a id="dLabel" data-target="#" href="" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
172
        <i class="glyphicon glyphicon-cog"></i>
173
        <span class="caret"></span>
174
      </a>
175
176
      <ul class="dropdown-menu" aria-labelledby="dLabel">
177
        <li><a href ='' onclick='inji.Ui.dataManagers.get(this).rowSelection("selectAll");return false;'>Выделить все</a></li>
178
        <li><a href ='' onclick='inji.Ui.dataManagers.get(this).rowSelection("unSelectAll");return false;'>Снять все</a></li>
179
        <li><a href ='' onclick='inji.Ui.dataManagers.get(this).rowSelection("inverse");return false;'>Инвертировать</a></li>
180
        <li role="separator" class="divider"></li>
181
          <?php
182
          foreach ($actions as $action => $actionParams) {
183
            if (class_exists($actionParams['className']) && $actionParams['className']::$groupAction) {
184
              echo "<li><a role='button' href ='#' onclick='inji.Ui.dataManagers.get(this).groupAction(\"" . str_replace('\\', '\\\\', $action) . "\");return false;'>{$actionParams['className']::$name}</a></li>";
185
            }
186
          }
187
          ?>
188
      </ul>
189
    </div>
190
    <?php
191
    $dropdown = ob_get_contents();
192
    ob_end_clean();
193
194
    $cols = [];
195
    $cols[] = ['label' => $dropdown];
196
    $cols['id'] = ['label' => '№', 'sortable' => true];
197
198
    $modelName = $this->modelName;
199
    foreach ($this->managerOptions['cols'] as $key => $col) {
200
      if (is_array($col)) {
201
        $colName = $key;
202
        $colOptions = $col;
203
      } else {
204
        $colName = $col;
205
        $colOptions = [];
206
      }
207
      $colInfo = [];
208
      if ($modelName) {
209
        $colInfo = $modelName::getColInfo($colName);
210
      }
211
      if (empty($colOptions['label']) && !empty($colInfo['label'])) {
212
        $colOptions['label'] = $colInfo['label'];
213
      } elseif (empty($colOptions['label'])) {
214
        $colOptions['label'] = $colName;
215
      }
216
      $cols[$colName] = $colOptions;
217
    }
218
    return $cols;
219
  }
220
221
  /**
222
   * Get rows for manager
223
   * 
224
   * @param array $params
225
   * @param object $model
226
   * @return type
227
   */
228
  public function getRows($params = [], $model = null) {
229
    $modelName = $this->modelName;
230
    if (!class_exists($modelName)) {
231
      return [];
232
    }
233 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...
234
      $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->managerName . '"');
235
      return [];
236
    }
237
    $modelName = $this->modelName;
238
    $queryParams = [];
239
    if (empty($params['all'])) {
240
      if (!empty($params['limit'])) {
241
        $this->limit = (int) $params['limit'];
242
      }
243
      if (!empty($params['page'])) {
244
        $this->page = (int) $params['page'];
245
      }
246
      $queryParams['limit'] = $this->limit;
247
      $queryParams['start'] = $this->page * $this->limit - $this->limit;
248
    }
249 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...
250
      $queryParams['where'][] = ['tree_path', $params['categoryPath'] . '%', 'LIKE'];
251
    }
252
    if (!empty($params['appType'])) {
253
      $queryParams['appType'] = $params['appType'];
254
    }
255
    if ($this->joins) {
256
      $queryParams['joins'] = $this->joins;
257
    }
258 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...
259
      foreach ($this->managerOptions['userGroupFilter'][\Users\User::$cur->group_id]['getRows'] as $colName => $colOptions) {
260
        if (!empty($colOptions['userCol'])) {
261
          if (strpos($colOptions['userCol'], ':')) {
262
            $rel = substr($colOptions['userCol'], 0, strpos($colOptions['userCol'], ':'));
263
            $param = substr($colOptions['userCol'], strpos($colOptions['userCol'], ':') + 1);
264
            $queryParams['where'][] = [$colName, \Users\User::$cur->$rel->$param];
265
          }
266
        } elseif (isset($colOptions['value'])) {
267
          $queryParams['where'][] = [$colName, $colOptions['value'], is_array($colOptions['value']) ? 'IN' : '='];
268
        }
269
      }
270
    }
271
    if (!empty($this->managerOptions['filters'])) {
272
      foreach ($this->managerOptions['filters'] as $col) {
273
        $colInfo = $modelName::getColInfo($col);
274
        switch ($colInfo['colParams']['type']) {
275 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...
276
            if (empty($params['filters'][$col]['value'])) {
277
              continue;
278
            }
279
            if (is_array($params['filters'][$col]['value'])) {
280
              foreach ($params['filters'][$col]['value'] as $key => $value) {
281
                if ($value === '') {
282
                  unset($params['filters'][$col]['value'][$key]);
283
                }
284
              }
285
            }
286
            if (!$params['filters'][$col]['value']) {
287
              continue;
288
            }
289
            $queryParams['where'][] = [$col, $params['filters'][$col]['value'], is_array($params['filters'][$col]['value']) ? 'IN' : '='];
290
            break;
291
          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...
292
293
            if (!isset($params['filters'][$col]['value']) || $params['filters'][$col]['value'] === '') {
294
              continue;
295
            }
296
            $queryParams['where'][] = [$col, $params['filters'][$col]['value']];
297
            break;
298
          case 'dateTime':
299 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...
300
            if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
301
              continue;
302
            }
303
            if (!empty($params['filters'][$col]['min'])) {
304
              $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
305
            }
306
            if (!empty($params['filters'][$col]['max'])) {
307
              if ($colInfo['colParams']['type'] == 'dateTime' && !strpos($params['filters'][$col]['max'], ' ')) {
308
309
                $date = $params['filters'][$col]['max'] . ' 23:59:59';
310
              } else {
311
                $date = $params['filters'][$col]['max'];
312
              }
313
              $queryParams['where'][] = [$col, $date, '<='];
314
            }
315
            break;
316 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...
317
            if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
318
              continue;
319
            }
320
            if (!empty($params['filters'][$col]['min'])) {
321
              $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
322
            }
323
            if (!empty($params['filters'][$col]['max'])) {
324
              $queryParams['where'][] = [$col, $params['filters'][$col]['max'], '<='];
325
            }
326
            break;
327
          case 'email':
328
          case 'text':
329
          case 'textarea':
330 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...
331
            if (empty($params['filters'][$col]['value'])) {
332
              continue;
333
            }
334
            switch ($params['filters'][$col]['compareType']) {
335
              case 'contains':
336
                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'] . '%', 'LIKE'];
337
                break;
338
              case 'equals':
339
                $queryParams['where'][] = [$col, $params['filters'][$col]['value']];
340
                break;
341
              case 'starts_with':
342
                $queryParams['where'][] = [$col, $params['filters'][$col]['value'] . '%', 'LIKE'];
343
                break;
344
              case 'ends_with':
345
                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'], 'LIKE'];
346
                break;
347
            }
348
            break;
349
        }
350
      }
351
    }
352
    if (!empty($params['mode']) && $params['mode'] == 'sort') {
353
      $queryParams['order'] = ['weight', 'asc'];
354
    } elseif (!empty($params['sortered']) && !empty($this->managerOptions['sortable'])) {
355
      foreach ($params['sortered'] as $key => $sortType) {
356
        $keys = array_keys($this->managerOptions['cols']);
357
        $colName = '';
358
        if (isset($keys[$key])) {
359
          if (is_array($this->managerOptions['cols'][$keys[$key]])) {
360
            $colName = $keys[$key];
361
          } else {
362
            $colName = $this->managerOptions['cols'][$keys[$key]];
363
          }
364
        }
365
        if ($colName && in_array($colName, $this->managerOptions['sortable'])) {
366
          $sortType = in_array($sortType, ['desc', 'asc']) ? $sortType : 'desc';
367
          $queryParams['order'][] = [$colName, $sortType];
368
        }
369
      }
370
    }
371
    if ($model && !empty($params['relation'])) {
372
      $relation = $model::getRelation($params['relation']);
373
      $items = $model->$params['relation']($queryParams);
374
    } else {
375
      $relation = false;
376
      $items = $modelName::getList($queryParams);
377
    }
378
    $rows = [];
379
    foreach ($items as $item) {
380
      if ($relation && !empty($relation['relModel'])) {
381
        $item = $relation['relModel']::get([[$item->index(), $item->id], [$model->index(), $model->id]]);
382
      }
383
      $row = [];
384
      $row[] = '<input type ="checkbox" name = "pk[]" value =' . $item->pk() . '>';
385
      $row[] = $item->pk();
386
      foreach ($this->managerOptions['cols'] as $key => $colName) {
387
        if (!empty($params['download'])) {
388
          $row[] = \Model::getColValue($item, is_array($colName) ? $key : $colName, true, false);
389
        } else {
390
          $row[] = DataManager::drawCol($item, is_array($colName) ? $key : $colName, $params, $this);
391
        }
392
      }
393
      $row[] = $this->rowButtons($item, $params);
394
      $rows[] = $row;
395
    }
396
    return $rows;
397
  }
398
399
  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...
400
    $modelName = get_class($item);
401
    if (!class_exists($modelName)) {
402
      return false;
403
    }
404
405
    if (!$originalCol) {
406
      $originalCol = $colName;
407
    }
408
    if (!$originalItem) {
409
      $originalItem = $item;
410
    }
411
412
    $relations = $modelName::relations();
413
    if (strpos($colName, ':') !== false && !empty($relations[substr($colName, 0, strpos($colName, ':'))])) {
414
      $rel = substr($colName, 0, strpos($colName, ':'));
415
      $col = substr($colName, strpos($colName, ':') + 1);
416
      if ($item->$rel) {
417
        return DataManager::drawCol($item->$rel, $col, $params, $dataManager, $originalCol, $originalItem);
418
      } else {
419
        return 'Не указано';
420
      }
421
    }
422
    if (!empty($modelName::$cols[$colName]['relation'])) {
423
      $type = !empty($relations[$modelName::$cols[$colName]['relation']]['type']) ? $relations[$modelName::$cols[$colName]['relation']]['type'] : 'to';
424
      switch ($type) {
425 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...
426
          $managerParams = ['relation' => $modelName::$cols[$colName]['relation']];
427
          $count = $item->{$modelName::$cols[$colName]['relation']}(array_merge($params, ['count' => 1]));
428
          $count = $count ? $count : 'Нет';
429
          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>";
430 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...
431
          $managerParams = ['relation' => $modelName::$cols[$colName]['relation']];
432
          $count = $item->{$modelName::$cols[$colName]['relation']}(array_merge($params, ['count' => 1]));
433
          $count = $count ? $count : 'Нет';
434
          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>";
435
        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...
436
          if ($item->{$modelName::$cols[$colName]['relation']}) {
437
            if (\App::$cur->name == 'admin') {
438
              $href = "<a href ='/admin/" . str_replace('\\', '/view/', $relations[$modelName::$cols[$colName]['relation']]['model']) . "/" . $item->{$modelName::$cols[$colName]['relation']}->pk() . "'>";
439
              if (!empty($modelName::$cols[$colName]['showCol'])) {
440
                $href .= $item->{$modelName::$cols[$colName]['relation']}->{$modelName::$cols[$colName]['showCol']};
441
              } else {
442
443
                $href .= $item->{$modelName::$cols[$colName]['relation']}->name();
444
              }
445
              $href .= '</a>';
446
              return $href;
447
            } else {
448
              return $item->{$modelName::$cols[$colName]['relation']}->name();
449
            }
450
          } else {
451
            return $item->$colName;
452
          }
453
      }
454
    } else {
455
      if (!empty($modelName::$cols[$colName]['view']['type'])) {
456
        switch ($modelName::$cols[$colName]['view']['type']) {
457
          case 'widget':
458
            ob_start();
459
            \App::$cur->view->widget($modelName::$cols[$colName]['view']['widget'], ['item' => $item, 'colName' => $colName, 'colParams' => $modelName::$cols[$colName]]);
460
            $content = ob_get_contents();
461
            ob_end_clean();
462
            return $content;
463
          case 'moduleMethod':
464
            return \App::$cur->{$modelName::$cols[$colName]['view']['module']}->{$modelName::$cols[$colName]['view']['method']}($item, $colName, $modelName::$cols[$colName]);
465
          case 'many':
466
            $managerParams = ['relation' => $modelName::$cols[$colName]['relation']];
467
            $count = $item->{$modelName::$cols[$colName]['relation']}(array_merge($params, ['count' => 1]));
468
            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>";
469
          default:
470
            return $item->$colName;
471
        }
472
      } elseif (!empty($modelName::$cols[$colName]['type'])) {
473
        if (\App::$cur->name == 'admin' && $originalCol == 'name' || ( $dataManager && !empty($dataManager->managerOptions['colToView']) && $dataManager->managerOptions['colToView'] == $originalCol)) {
474
          $formName = $dataManager && !empty($dataManager->managerOptions['editForm']) ? $dataManager->managerOptions['editForm'] : 'manager';
475
          $redirectUrl = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/admin/' . str_replace('\\', '/', get_class($originalItem));
476
          return "<a href ='/admin/" . str_replace('\\', '/view/', get_class($originalItem)) . "/{$originalItem->id}?formName={$formName}&redirectUrl={$redirectUrl}'>{$item->$colName}</a>";
477
        } elseif (\App::$cur->name == 'admin' && $colName == 'name') {
478
          $redirectUrl = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/admin/' . str_replace('\\', '/', get_class($originalItem));
479
          return "<a href ='/admin/" . str_replace('\\', '/view/', get_class($item)) . "/{$item->id}?redirectUrl={$redirectUrl}'>{$item->$colName}</a>";
480
        } else {
481
          return \Model::resloveTypeValue($item, $colName);
482
        }
483
      } else {
484
        return $item->$colName;
485
      }
486
    }
487
  }
488
489
  public function rowButtons($item, $params) {
490
    $modelName = $this->modelName;
491
    if (!class_exists($modelName)) {
492
      return false;
493
    }
494
    ob_start();
495
    $widgetName = !empty($this->managerOptions['rowButtonsWidget']) ? $this->managerOptions['rowButtonsWidget'] : 'Ui\DataManager/rowButtons';
496
    \App::$cur->view->widget($widgetName, [
497
        'dataManager' => $this,
498
        'item' => $item,
499
        'params' => $params
500
    ]);
501
    $buttons = ob_get_contents();
502
    ob_end_clean();
503
    return $buttons;
504
  }
505
506
  public function getPages($params = [], $model = null) {
507
    $modelName = $this->modelName;
508
    if (!class_exists($modelName)) {
509
      return [];
510
    }
511 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...
512
      $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->managerName . '"');
513
      return [];
514
    }
515
    if (!empty($params['limit'])) {
516
      $this->limit = (int) $params['limit'];
517
    }
518
    if (!empty($params['page'])) {
519
      $this->page = (int) $params['page'];
520
    }
521
    $queryParams = [
522
        'count' => true
523
    ];
524
    $modelName = $this->modelName;
525 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...
526
      $queryParams['where'][] = ['tree_path', $params['categoryPath'] . '%', 'LIKE'];
527
    }
528 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...
529
      foreach ($this->managerOptions['userGroupFilter'][\Users\User::$cur->group_id]['getRows'] as $colName => $colOptions) {
530
        if (!empty($colOptions['userCol'])) {
531
          if (strpos($colOptions['userCol'], ':')) {
532
            $rel = substr($colOptions['userCol'], 0, strpos($colOptions['userCol'], ':'));
533
            $param = substr($colOptions['userCol'], strpos($colOptions['userCol'], ':') + 1);
534
            $queryParams['where'][] = [$colName, \Users\User::$cur->$rel->$param];
535
          }
536
        } elseif (isset($colOptions['value'])) {
537
          $queryParams['where'][] = [$colName, $colOptions['value'], is_array($colOptions['value']) ? 'IN' : '='];
538
        }
539
      }
540
    }
541
    $modelName = $this->modelName;
542
    if (!empty($this->managerOptions['filters'])) {
543
      foreach ($this->managerOptions['filters'] as $col) {
544
        $colInfo = $modelName::getColInfo($col);
545
        switch ($colInfo['colParams']['type']) {
546 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...
547
            if (empty($params['filters'][$col]['value'])) {
548
              continue;
549
            }
550
            if (is_array($params['filters'][$col]['value'])) {
551
              foreach ($params['filters'][$col]['value'] as $key => $value) {
552
                if ($value === '') {
553
                  unset($params['filters'][$col]['value'][$key]);
554
                }
555
              }
556
            }
557
            if (!$params['filters'][$col]['value']) {
558
              continue;
559
            }
560
            $queryParams['where'][] = [$col, $params['filters'][$col]['value'], is_array($params['filters'][$col]['value']) ? 'IN' : '='];
561
            break;
562
          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...
563
564
            if (empty($params['filters'][$col]['value'])) {
565
              continue;
566
            }
567
            $queryParams['where'][] = [$col, '1'];
568
            break;
569
          case 'dateTime':
570 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...
571
            if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
572
              continue;
573
            }
574
            if (!empty($params['filters'][$col]['min'])) {
575
              $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
576
            }
577
            if (!empty($params['filters'][$col]['max'])) {
578
              if ($colInfo['colParams']['type'] == 'dateTime' && !strpos($params['filters'][$col]['max'], ' ')) {
579
580
                $date = $params['filters'][$col]['max'] . ' 23:59:59';
581
              } else {
582
                $date = $params['filters'][$col]['max'];
583
              }
584
              $queryParams['where'][] = [$col, $date, '<='];
585
            }
586
            break;
587 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...
588
            if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
589
              continue;
590
            }
591
            if (!empty($params['filters'][$col]['min'])) {
592
              $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
593
            }
594
            if (!empty($params['filters'][$col]['max'])) {
595
              $queryParams['where'][] = [$col, $params['filters'][$col]['max'], '<='];
596
            }
597
            break;
598
          case 'email':
599
          case 'text':
600
          case 'textarea':
601 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...
602
            if (empty($params['filters'][$col]['value'])) {
603
              continue;
604
            }
605
            switch ($params['filters'][$col]['compareType']) {
606
              case 'contains':
607
                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'] . '%', 'LIKE'];
608
                break;
609
              case 'equals':
610
                $queryParams['where'][] = [$col, $params['filters'][$col]['value']];
611
                break;
612
              case 'starts_with':
613
                $queryParams['where'][] = [$col, $params['filters'][$col]['value'] . '%', 'LIKE'];
614
                break;
615
              case 'ends_with':
616
                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'], 'LIKE'];
617
                break;
618
            }
619
            break;
620
        }
621
      }
622
    }
623
    if ($model && !empty($params['relation'])) {
624
      $count = $model->$params['relation']($queryParams);
625
    } else {
626
      $count = $modelName::getCount($queryParams);
627
    }
628
    $pages = new Pages([
629
        'limit' => $this->limit,
630
        'page' => $this->page,
631
            ], [
632
        'count' => $count,
633
        'dataManager' => $this
634
    ]);
635
    return $pages;
636
  }
637
638
  public function preDraw($params = [], $model = null) {
639
    $this->predraw = true;
640
641
    $cols = $this->getCols();
642
643
    $this->table = new Table();
644
    $tableCols = [];
645
    foreach ($cols as $colName => $colOptions) {
646
      $tableCols[] = !empty($colOptions['label']) ? $colOptions['label'] : $colName;
647
    }
648
    $tableCols[] = '';
649
    $this->table->class .=' datamanagertable';
650
    $this->table->setCols($tableCols);
651
  }
652
653
  public function draw($params = [], $model = null) {
654
    if (!$this->predraw) {
655
      $this->preDraw($params, $model);
656
    }
657
    \App::$cur->view->widget('Ui\DataManager/DataManager', [
658
        'dataManager' => $this,
659
        'model' => $model,
660
        'table' => $this->table,
661
        'params' => $params
662
    ]);
663
  }
664
665
  public function drawCategorys() {
666
    if (!class_exists($this->modelName)) {
667
      return false;
668
    }
669 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...
670
      $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->managerName . '"');
671
      return [];
672
    }
673
    $tree = new Tree();
674
    $tree->ul($this->managerOptions['categorys']['model'], 0, function($category) {
675
      $path = $category->tree_path . ($category->pk() ? $category->pk() . "/" : '');
676
      $cleanClassName = str_replace('\\', '\\\\', get_class($category));
677
      return "<a href='#' onclick='inji.Ui.dataManagers.get(this).switchCategory(this);return false;' data-index='{$category->index()}' data-path ='{$path}' data-id='{$category->pk()}' data-model='{$this->managerOptions['categorys']['model']}'> {$category->name}</a> 
678
                
679
                    <a href = '#' class ='glyphicon glyphicon-edit'   onclick = 'inji.Ui.forms.popUp(\"{$cleanClassName}:{$category->pk()}\")'></a>&nbsp;
680
                    <a href = '#' class ='glyphicon glyphicon-remove' onclick = 'inji.Ui.dataManagers.get(this).delCategory({$category->pk()});return false;'></a>";
681
    });
682
    ?>
683
    <?php
684
  }
685
686
  /**
687
   * Draw error message
688
   * 
689
   * @param string $errorText
690
   */
691
  public function drawError($errorText) {
692
    echo $errorText;
693
  }
694
695
  /**
696
   * Check access cur user to manager with name in param
697
   * 
698
   * @return boolean
699
   */
700
  public function checkAccess() {
701
    if (\App::$cur->Access && !\App::$cur->Access->checkAccess($this)) {
702
      return false;
703
    }
704
705 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...
706
      return false;
707
    }
708 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...
709
      return true;
710
    }
711
    if ($this->managerName == 'manager' && !\Users\User::$cur->isAdmin()) {
712
      return false;
713
    }
714
    return true;
715
  }
716
717
}
718