Completed
Push — master ( 0afdc4...0e57e6 )
by Alexey
04:27
created

DataManager::getButtons()   F

Complexity

Conditions 12
Paths 960

Size

Total Lines 65
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 43
nc 960
nop 2
dl 0
loc 65
rs 3.0769
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
    if (!empty($modelName::$forms[$formParams['formName']])) {
123
      $aform = new ActiveForm(new $modelName, $formParams['formName']);
124
      if ($aform->checkAccess()) {
125
        $buttons[] = [
126
            'text' => 'Создать ' . $name,
127
            'onclick' => 'inji.Ui.dataManagers.get(this).newItem("' . str_replace('\\', '\\\\', $modelName) . '",' . json_encode($formParams) . ');',
128
        ];
129
      }
130
    }
131
132
    return $buttons;
133
  }
134
135
  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...
136
    $actions = [
137
        'Open' => ['className' => 'Open'], 'Edit' => ['className' => 'Edit'], 'Delete' => ['className' => 'Delete']
138
    ];
139
    if (isset($this->managerOptions['actions'])) {
140
      $actions = array_merge($actions, $this->managerOptions['actions']);
141
    }
142
    $return = [];
143
    foreach ($actions as $key => $action) {
144
      if ($action === false) {
145
        continue;
146
      }
147
      if (is_array($action)) {
148
        if (!empty($action['access']['groups']) && !in_array(\Users\User::$cur->group_id, $action['access']['groups'])) {
149
          continue;
150
        }
151
        if (empty($action['className'])) {
152
          $action['className'] = $key;
153
        }
154
        $return[$key] = $action;
155
      } else {
156
        $key = $action;
157
        $return[$key] = [
158
            'className' => $action
159
        ];
160
      }
161
      $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'];
162
      if (!class_exists($return[$key]['className']) || ($onlyGroupActions && !$return[$key]['className']::$groupAction)) {
163
        unset($return[$key]);
164
      }
165
    }
166
    return $return;
167
  }
168
169
  /**
170
   * Get cols for manager
171
   * 
172
   * @return string
173
   */
174
  public function getCols() {
175
    $actions = $this->getActions();
176
    ob_start();
177
    ?>
178
    <div class="dropdown">
179
      <a id="dLabel" data-target="#" href="" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
180
        <i class="glyphicon glyphicon-cog"></i>
181
        <span class="caret"></span>
182
      </a>
183
184
      <ul class="dropdown-menu" aria-labelledby="dLabel">
185
        <li><a href ='' onclick='inji.Ui.dataManagers.get(this).rowSelection("selectAll");return false;'>Выделить все</a></li>
186
        <li><a href ='' onclick='inji.Ui.dataManagers.get(this).rowSelection("unSelectAll");return false;'>Снять все</a></li>
187
        <li><a href ='' onclick='inji.Ui.dataManagers.get(this).rowSelection("inverse");return false;'>Инвертировать</a></li>
188
        <li role="separator" class="divider"></li>
189
          <?php
190
          foreach ($actions as $action => $actionParams) {
191
            if (class_exists($actionParams['className']) && $actionParams['className']::$groupAction) {
192
              echo "<li><a role='button' href ='#' onclick='inji.Ui.dataManagers.get(this).groupAction(\"" . str_replace('\\', '\\\\', $action) . "\");return false;'>{$actionParams['className']::$name}</a></li>";
193
            }
194
          }
195
          ?>
196
      </ul>
197
    </div>
198
    <?php
199
    $dropdown = ob_get_contents();
200
    ob_end_clean();
201
202
    $cols = [];
203
    $cols[] = ['label' => $dropdown];
204
    $cols['id'] = ['label' => '№', 'sortable' => true];
205
206
    $modelName = $this->modelName;
207
    foreach ($this->managerOptions['cols'] as $key => $col) {
208
      if (is_array($col)) {
209
        $colName = $key;
210
        $colOptions = $col;
211
      } else {
212
        $colName = $col;
213
        $colOptions = [];
214
      }
215
      $colInfo = [];
216
      if ($modelName) {
217
        $colInfo = $modelName::getColInfo($colName);
218
      }
219
      if (empty($colOptions['label']) && !empty($colInfo['label'])) {
220
        $colOptions['label'] = $colInfo['label'];
221
      } elseif (empty($colOptions['label'])) {
222
        $colOptions['label'] = $colName;
223
      }
224
      $cols[$colName] = $colOptions;
225
    }
226
    return $cols;
227
  }
228
229
  /**
230
   * Get rows for manager
231
   * 
232
   * @param array $params
233
   * @param object $model
234
   * @return type
235
   */
236
  public function getRows($params = [], $model = null) {
1 ignored issue
show
Coding Style introduced by
getRows 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...
237
    $modelName = $this->modelName;
238
    if (!class_exists($modelName)) {
239
      return [];
240
    }
241 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...
242
      $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->managerName . '"');
243
      return [];
244
    }
245
    $modelName = $this->modelName;
246
    $queryParams = [];
247
    if (empty($params['all'])) {
248
      if (!empty($params['limit'])) {
249
        $this->limit = (int) $params['limit'];
250
      }
251
      if (!empty($params['page'])) {
252
        $this->page = (int) $params['page'];
253
      }
254
      $queryParams['limit'] = $this->limit;
255
      $queryParams['start'] = $this->page * $this->limit - $this->limit;
256
    }
257 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...
258
      $queryParams['where'][] = ['tree_path', $params['categoryPath'] . '%', 'LIKE'];
259
    }
260
    if (!empty($params['appType'])) {
261
      $queryParams['appType'] = $params['appType'];
262
    }
263
    if ($this->joins) {
264
      $queryParams['joins'] = $this->joins;
265
    }
266 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...
267
      foreach ($this->managerOptions['userGroupFilter'][\Users\User::$cur->group_id]['getRows'] as $colName => $colOptions) {
268
        if (!empty($colOptions['userCol'])) {
269
          $queryParams['where'][] = [$colName, \Model::getColValue(\Users\User::$cur, $colOptions['userCol'])];
270
        } elseif (isset($colOptions['value'])) {
271
          if (is_array($colOptions['value'])) {
272
            foreach ($colOptions['value'] as $key => $value) {
273
              if ($key === 'userCol') {
274
                $colOptions['value'][$key] = \Model::getColValue(\Users\User::$cur, $value);
275
              }
276
            }
277
          }
278
          $queryParams['where'][] = [$colName, $colOptions['value'], is_array($colOptions['value']) ? 'IN' : '='];
279
        }
280
      }
281
    }
282
    if (!empty($this->managerOptions['filters'])) {
283
      foreach ($this->managerOptions['filters'] as $col) {
284
        $colInfo = $modelName::getColInfo($col);
285
        switch ($colInfo['colParams']['type']) {
286 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...
287
            if (empty($params['filters'][$col]['value'])) {
288
              continue;
289
            }
290
            if (is_array($params['filters'][$col]['value'])) {
291
              foreach ($params['filters'][$col]['value'] as $key => $value) {
292
                if ($value === '') {
293
                  unset($params['filters'][$col]['value'][$key]);
294
                }
295
              }
296
            }
297
            if (!$params['filters'][$col]['value']) {
298
              continue;
299
            }
300
            $queryParams['where'][] = [$col, $params['filters'][$col]['value'], is_array($params['filters'][$col]['value']) ? 'IN' : '='];
301
            break;
302
          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...
303
304
            if (!isset($params['filters'][$col]['value']) || $params['filters'][$col]['value'] === '') {
305
              continue;
306
            }
307
            $queryParams['where'][] = [$col, $params['filters'][$col]['value']];
308
            break;
309
          case 'dateTime':
310 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...
311
            if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
312
              continue;
313
            }
314
            if (!empty($params['filters'][$col]['min'])) {
315
              $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
316
            }
317
            if (!empty($params['filters'][$col]['max'])) {
318
              if ($colInfo['colParams']['type'] == 'dateTime' && !strpos($params['filters'][$col]['max'], ' ')) {
319
320
                $date = $params['filters'][$col]['max'] . ' 23:59:59';
321
              } else {
322
                $date = $params['filters'][$col]['max'];
323
              }
324
              $queryParams['where'][] = [$col, $date, '<='];
325
            }
326
            break;
327 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...
328
            if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
329
              continue;
330
            }
331
            if (!empty($params['filters'][$col]['min'])) {
332
              $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
333
            }
334
            if (!empty($params['filters'][$col]['max'])) {
335
              $queryParams['where'][] = [$col, $params['filters'][$col]['max'], '<='];
336
            }
337
            break;
338
          case 'email':
339
          case 'text':
340
          case 'textarea':
341 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...
342
            if (empty($params['filters'][$col]['value'])) {
343
              continue;
344
            }
345
            switch ($params['filters'][$col]['compareType']) {
346
              case 'contains':
347
                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'] . '%', 'LIKE'];
348
                break;
349
              case 'equals':
350
                $queryParams['where'][] = [$col, $params['filters'][$col]['value']];
351
                break;
352
              case 'starts_with':
353
                $queryParams['where'][] = [$col, $params['filters'][$col]['value'] . '%', 'LIKE'];
354
                break;
355
              case 'ends_with':
356
                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'], 'LIKE'];
357
                break;
358
            }
359
            break;
360
        }
361
      }
362
    }
363
    if (!empty($params['mode']) && $params['mode'] == 'sort') {
364
      $queryParams['order'] = ['weight', 'asc'];
365
    } elseif (!empty($params['sortered']) && !empty($this->managerOptions['sortable'])) {
366
      foreach ($params['sortered'] as $key => $sortType) {
367
        $keys = array_keys($this->managerOptions['cols']);
368
        $colName = '';
369
        if (isset($keys[$key])) {
370
          if (is_array($this->managerOptions['cols'][$keys[$key]])) {
371
            $colName = $keys[$key];
372
          } else {
373
            $colName = $this->managerOptions['cols'][$keys[$key]];
374
          }
375
        }
376
        if ($colName && in_array($colName, $this->managerOptions['sortable'])) {
377
          $sortType = in_array($sortType, ['desc', 'asc']) ? $sortType : 'desc';
378
          $queryParams['order'][] = [$colName, $sortType];
379
        }
380
      }
381
    }
382
    if ($model && !empty($params['relation'])) {
383
      $relation = $model::getRelation($params['relation']);
384
      $items = $model->$params['relation']($queryParams);
385
    } else {
386
      $relation = false;
387
      $items = $modelName::getList($queryParams);
388
    }
389
    $rows = [];
390
    foreach ($items as $item) {
391
      if ($relation && !empty($relation['relModel'])) {
392
        $item = $relation['relModel']::get([[$item->index(), $item->id], [$model->index(), $model->id]]);
393
      }
394
      $row = [];
395
      $row[] = '<input type ="checkbox" name = "pk[]" value =' . $item->pk() . '>';
396
      $redirectUrl = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/admin/' . str_replace('\\', '%5C', get_class($originalItem));
0 ignored issues
show
Bug introduced by
The variable $originalItem does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
397
      $row[] = "<a href ='/admin/" . $item->genViewLink() . "?redirectUrl={$redirectUrl}'>{$item->pk()}</a>";
398
      foreach ($this->managerOptions['cols'] as $key => $colName) {
399
        if (!empty($params['download'])) {
400
          $row[] = \Model::getColValue($item, is_array($colName) ? $key : $colName, true, false);
401
        } else {
402
          $row[] = DataManager::drawCol($item, is_array($colName) ? $key : $colName, $params, $this);
403
        }
404
      }
405
      $row[] = $this->rowButtons($item, $params);
406
      $rows[] = $row;
407
    }
408
    return $rows;
409
  }
410
411
  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...
412
    $modelName = get_class($item);
413
    if (!class_exists($modelName)) {
414
      return false;
415
    }
416
417
    if (!$originalCol) {
418
      $originalCol = $colName;
419
    }
420
    if (!$originalItem) {
421
      $originalItem = $item;
422
    }
423
424
    $relations = $modelName::relations();
425
    if (strpos($colName, ':') !== false && !empty($relations[substr($colName, 0, strpos($colName, ':'))])) {
426
      $rel = substr($colName, 0, strpos($colName, ':'));
427
      $col = substr($colName, strpos($colName, ':') + 1);
428
      if ($item->$rel) {
429
        return DataManager::drawCol($item->$rel, $col, $params, $dataManager, $originalCol, $originalItem);
430
      } else {
431
        return 'Не указано';
432
      }
433
    }
434
    if (!empty($modelName::$cols[$colName]['relation'])) {
435
      $type = !empty($relations[$modelName::$cols[$colName]['relation']]['type']) ? $relations[$modelName::$cols[$colName]['relation']]['type'] : 'to';
436
      switch ($type) {
437 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...
438
          $managerParams = ['relation' => $modelName::$cols[$colName]['relation']];
439
          $count = $item->{$modelName::$cols[$colName]['relation']}(array_merge($params, ['count' => 1]));
440
          $count = $count ? $count : 'Нет';
441
          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>";
442 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...
443
          $managerParams = ['relation' => $modelName::$cols[$colName]['relation']];
444
          $count = $item->{$modelName::$cols[$colName]['relation']}(array_merge($params, ['count' => 1]));
445
          $count = $count ? $count : 'Нет';
446
          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>";
447
        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...
448
          if ($item->{$modelName::$cols[$colName]['relation']}) {
449
            if (\App::$cur->name == 'admin') {
450
              $href = "<a href ='/admin/" . $item->{$modelName::$cols[$colName]['relation']}->genViewLink() . "'>";
451
              if (!empty($modelName::$cols[$colName]['showCol'])) {
452
                $href .= $item->{$modelName::$cols[$colName]['relation']}->{$modelName::$cols[$colName]['showCol']};
453
              } else {
454
455
                $href .= $item->{$modelName::$cols[$colName]['relation']}->name();
456
              }
457
              $href .= '</a>';
458
              return $href;
459
            } else {
460
              return $item->{$modelName::$cols[$colName]['relation']}->name();
461
            }
462
          } else {
463
            return $item->$colName;
464
          }
465
      }
466
    } else {
467
      if (!empty($modelName::$cols[$colName]['view']['type'])) {
468
        switch ($modelName::$cols[$colName]['view']['type']) {
469
          case 'widget':
470
            ob_start();
471
            \App::$cur->view->widget($modelName::$cols[$colName]['view']['widget'], ['item' => $item, 'colName' => $colName, 'colParams' => $modelName::$cols[$colName]]);
472
            $content = ob_get_contents();
473
            ob_end_clean();
474
            return $content;
475
          case 'moduleMethod':
476
            return \App::$cur->{$modelName::$cols[$colName]['view']['module']}->{$modelName::$cols[$colName]['view']['method']}($item, $colName, $modelName::$cols[$colName]);
477
          case 'many':
478
            $managerParams = ['relation' => $modelName::$cols[$colName]['relation']];
479
            $count = $item->{$modelName::$cols[$colName]['relation']}(array_merge($params, ['count' => 1]));
480
            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>";
481
          default:
482
            return $item->$colName;
483
        }
484
      } elseif (!empty($modelName::$cols[$colName]['type'])) {
485
        if (\App::$cur->name == 'admin' && $originalCol == 'name' || ( $dataManager && !empty($dataManager->managerOptions['colToView']) && $dataManager->managerOptions['colToView'] == $originalCol)) {
486
          $formName = $dataManager && !empty($dataManager->managerOptions['editForm']) ? $dataManager->managerOptions['editForm'] : 'manager';
487
          $redirectUrl = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/admin/' . str_replace('\\', '/', get_class($originalItem));
488
          return "<a href ='/admin/{$originalItem->genViewLink()}?formName={$formName}&redirectUrl={$redirectUrl}'>{$item->$colName}</a>";
489
        } elseif (\App::$cur->name == 'admin' && $colName == 'name') {
490
          $redirectUrl = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/admin/' . str_replace('\\', '/', get_class($originalItem));
491
          return "<a href ='/admin/{$item->genViewLink()}?redirectUrl={$redirectUrl}'>{$item->$colName}</a>";
492
        } elseif ($modelName::$cols[$colName]['type'] == 'html') {
493
          $uid = \Tools::randomString();
494
          $script = "<script>inji.onLoad(function(){
495
            var el{$uid}=$('#{$uid}');
496
            var height{$uid} = el{$uid}.height();
497
            el{$uid}.css('maxHeight','none');
498
            function el{$uid}Toggle(){
499
              console.log($('#{$uid}').css('height'));
500
                
501
              if( $('#{$uid}').css('height')=='44px'){
502
                $('#{$uid}').css('height','auto');
503
                  var height = $('#{$uid}').height();
504
                  $('#{$uid}').css('height','44px');
505
                  $('#{$uid}').animate({height:height});
506
                  $('#{$uid}').next().text('Свернуть' )
507
                }
508
                else {
509
                  $('#{$uid}').next().text('Развернуть')
510
                  $('#{$uid}').animate({height:'44px'});
511
                }
512
            }
513
            window['el{$uid}Toggle']= el{$uid}Toggle;
514
            if(el{$uid}.height()>height{$uid}){
515
              el{$uid}.css('height','44px');
516
                
517
              el{$uid}.after('<a href=\"#\" onclick=\"el{$uid}Toggle();return false;\">Развернуть</a>');
518
            }
519
            })</script>";
520
          return "<div id = '{$uid}' style='max-height:44px;overflow:hidden;'>{$item->$colName}</div>" . $script;
521
        } else {
522
          return \Model::resloveTypeValue($item, $colName);
523
        }
524
      } else {
525
        return $item->$colName;
526
      }
527
    }
528
  }
529
530
  public function rowButtons($item, $params) {
531
    $modelName = $this->modelName;
532
    if (!class_exists($modelName)) {
533
      return false;
534
    }
535
    ob_start();
536
    $widgetName = !empty($this->managerOptions['rowButtonsWidget']) ? $this->managerOptions['rowButtonsWidget'] : 'Ui\DataManager/rowButtons';
537
    \App::$cur->view->widget($widgetName, [
538
        'dataManager' => $this,
539
        'item' => $item,
540
        'params' => $params
541
    ]);
542
    $buttons = ob_get_contents();
543
    ob_end_clean();
544
    return $buttons;
545
  }
546
547
  public function getPages($params = [], $model = null) {
548
    $modelName = $this->modelName;
549
    if (!class_exists($modelName)) {
550
      return [];
551
    }
552 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...
553
      $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->managerName . '"');
554
      return [];
555
    }
556
    if (!empty($params['limit'])) {
557
      $this->limit = (int) $params['limit'];
558
    }
559
    if (!empty($params['page'])) {
560
      $this->page = (int) $params['page'];
561
    }
562
    $queryParams = [
563
        'count' => true
564
    ];
565
    $modelName = $this->modelName;
566 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...
567
      $queryParams['where'][] = ['tree_path', $params['categoryPath'] . '%', 'LIKE'];
568
    }
569 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...
570
      foreach ($this->managerOptions['userGroupFilter'][\Users\User::$cur->group_id]['getRows'] as $colName => $colOptions) {
571
        if (!empty($colOptions['userCol'])) {
572
          $queryParams['where'][] = [$colName, \Model::getColValue(\Users\User::$cur, $colOptions['userCol'])];
573
        } elseif (isset($colOptions['value'])) {
574
          if (is_array($colOptions['value'])) {
575
            foreach ($colOptions['value'] as $key => $value) {
576
              if ($key === 'userCol') {
577
                $colOptions['value'][$key] = \Model::getColValue(\Users\User::$cur, $value);
578
              }
579
            }
580
          }
581
          $queryParams['where'][] = [$colName, $colOptions['value'], is_array($colOptions['value']) ? 'IN' : '='];
582
        }
583
      }
584
    }
585
    $modelName = $this->modelName;
586
    if (!empty($this->managerOptions['filters'])) {
587
      foreach ($this->managerOptions['filters'] as $col) {
588
        $colInfo = $modelName::getColInfo($col);
589
        switch ($colInfo['colParams']['type']) {
590 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...
591
            if (empty($params['filters'][$col]['value'])) {
592
              continue;
593
            }
594
            if (is_array($params['filters'][$col]['value'])) {
595
              foreach ($params['filters'][$col]['value'] as $key => $value) {
596
                if ($value === '') {
597
                  unset($params['filters'][$col]['value'][$key]);
598
                }
599
              }
600
            }
601
            if (!$params['filters'][$col]['value']) {
602
              continue;
603
            }
604
            $queryParams['where'][] = [$col, $params['filters'][$col]['value'], is_array($params['filters'][$col]['value']) ? 'IN' : '='];
605
            break;
606
          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...
607
608
            if (empty($params['filters'][$col]['value'])) {
609
              continue;
610
            }
611
            $queryParams['where'][] = [$col, '1'];
612
            break;
613
          case 'dateTime':
614 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...
615
            if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
616
              continue;
617
            }
618
            if (!empty($params['filters'][$col]['min'])) {
619
              $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
620
            }
621
            if (!empty($params['filters'][$col]['max'])) {
622
              if ($colInfo['colParams']['type'] == 'dateTime' && !strpos($params['filters'][$col]['max'], ' ')) {
623
624
                $date = $params['filters'][$col]['max'] . ' 23:59:59';
625
              } else {
626
                $date = $params['filters'][$col]['max'];
627
              }
628
              $queryParams['where'][] = [$col, $date, '<='];
629
            }
630
            break;
631 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...
632
            if (empty($params['filters'][$col]['min']) && empty($params['filters'][$col]['max'])) {
633
              continue;
634
            }
635
            if (!empty($params['filters'][$col]['min'])) {
636
              $queryParams['where'][] = [$col, $params['filters'][$col]['min'], '>='];
637
            }
638
            if (!empty($params['filters'][$col]['max'])) {
639
              $queryParams['where'][] = [$col, $params['filters'][$col]['max'], '<='];
640
            }
641
            break;
642
          case 'email':
643
          case 'text':
644
          case 'textarea':
645 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...
646
            if (empty($params['filters'][$col]['value'])) {
647
              continue;
648
            }
649
            switch ($params['filters'][$col]['compareType']) {
650
              case 'contains':
651
                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'] . '%', 'LIKE'];
652
                break;
653
              case 'equals':
654
                $queryParams['where'][] = [$col, $params['filters'][$col]['value']];
655
                break;
656
              case 'starts_with':
657
                $queryParams['where'][] = [$col, $params['filters'][$col]['value'] . '%', 'LIKE'];
658
                break;
659
              case 'ends_with':
660
                $queryParams['where'][] = [$col, '%' . $params['filters'][$col]['value'], 'LIKE'];
661
                break;
662
            }
663
            break;
664
        }
665
      }
666
    }
667
    if ($model && !empty($params['relation'])) {
668
      $count = $model->$params['relation']($queryParams);
669
    } else {
670
      $count = $modelName::getCount($queryParams);
671
    }
672
    $pages = new Pages([
673
        'limit' => $this->limit,
674
        'page' => $this->page,
675
            ], [
676
        'count' => $count,
677
        'dataManager' => $this
678
    ]);
679
    return $pages;
680
  }
681
682
  public function preDraw($params = [], $model = null) {
683
    $this->predraw = true;
684
685
    $cols = $this->getCols();
686
687
    $this->table = new Table();
688
    $tableCols = [];
689
    foreach ($cols as $colName => $colOptions) {
690
      $tableCols[] = !empty($colOptions['label']) ? $colOptions['label'] : $colName;
691
    }
692
    $tableCols[] = '';
693
    $this->table->class .=' datamanagertable';
694
    $this->table->setCols($tableCols);
695
  }
696
697
  public function draw($params = [], $model = null) {
698
    if (!$this->predraw) {
699
      $this->preDraw($params, $model);
700
    }
701
    \App::$cur->view->widget('Ui\DataManager/DataManager', [
702
        'dataManager' => $this,
703
        'model' => $model,
704
        'table' => $this->table,
705
        'params' => $params
706
    ]);
707
  }
708
709
  public function drawCategorys() {
710
    if (!class_exists($this->modelName)) {
711
      return false;
712
    }
713 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...
714
      $this->drawError('you not have access to "' . $this->modelName . '" manager with name: "' . $this->managerName . '"');
715
      return [];
716
    }
717
    $tree = new Tree();
718
    $tree->ul($this->managerOptions['categorys']['model'], 0, function($category) {
719
      $path = $category->tree_path . ($category->pk() ? $category->pk() . "/" : '');
720
      $cleanClassName = str_replace('\\', '\\\\', get_class($category));
721
      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> 
722
                
723
                    <a href = '#' class ='glyphicon glyphicon-edit'   onclick = 'inji.Ui.forms.popUp(\"{$cleanClassName}:{$category->pk()}\")'></a>&nbsp;
724
                    <a href = '#' class ='glyphicon glyphicon-remove' onclick = 'inji.Ui.dataManagers.get(this).delCategory({$category->pk()});return false;'></a>";
725
    });
726
    ?>
727
    <?php
728
  }
729
730
  /**
731
   * Draw error message
732
   * 
733
   * @param string $errorText
734
   */
735
  public function drawError($errorText) {
736
    echo $errorText;
737
  }
738
739
  /**
740
   * Check access cur user to manager with name in param
741
   * 
742
   * @return boolean
743
   */
744
  public function checkAccess() {
745
    if (\App::$cur->Access && !\App::$cur->Access->checkAccess($this)) {
746
      return false;
747
    }
748
749 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...
750
      return false;
751
    }
752 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...
753
      return true;
754
    }
755
    if ($this->managerName == 'manager' && !\Users\User::$cur->isAdmin()) {
756
      return false;
757
    }
758
    return true;
759
  }
760
761
}
762