Passed
Branch master (3b5440)
by refat
04:05
created

UsersController   F

Complexity

Total Complexity 73

Size/Duplication

Total Lines 402
Duplicated Lines 0 %

Importance

Changes 4
Bugs 1 Features 1
Metric Value
eloc 255
c 4
b 1
f 1
dl 0
loc 402
rs 2.56
wmc 73

13 Methods

Rating   Name   Duplication   Size   Complexity  
A formatUsers() 0 13 2
A index() 0 11 1
A row() 0 21 1
F filter() 0 124 22
F add() 0 96 18
A updateUser() 0 3 1
B update() 0 39 9
A new() 0 7 1
A isUserNotFound() 0 3 1
A isValuesAreTheSame() 0 7 4
A userUpdateMsg() 0 10 3
A validatorFails() 0 14 5
A isUserNew() 0 28 5

How to fix   Complexity   

Complex Class

Complex classes like UsersController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use UsersController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace App\Controllers\Admin;
4
5
use System\Controller as Controller;
6
use RandomLib\Factory as Factory;
7
8
class UsersController extends Controller
9
{
10
  public function index()
11
  {
12
    $users = $this->load->model('User')->users();
13
    $usersformatted = $this->formatUsers($users);
14
    $countries = $this->countries('all', 'name');
15
16
    $context = [
17
      'users' => $usersformatted,
18
      'countries' => $countries,
19
    ];
20
    return $this->view->render('admin/pages/users/users', $context);
21
  }
22
23
  public function row()
24
  {
25
    $id = userId();
26
    $model = $this->load->model('User');
27
    $user = $model->user($id);
28
29
    $user->new = $this->isUserNew($user->registration);
30
    $user->registration = $this->changeFormatDate($user->registration);
31
    $user->last_login = $this->changeFormatDate($user->last_login);
32
    $user->last_logout = $this->changeFormatDate($user->last_logout);
33
    $user->birthday = $this->changeFormatDate($user->birthday, ['Y-m-d', 'd M Y']);
34
    $user->country_icon = $this->countries($user->country);
35
36
    $countries = $this->countries('all', 'name');
37
    $countries_options = implode(',', $countries);
38
39
    $context = [
40
      'user' => $user,
41
      'countries_options' => $countries_options,
42
    ];
43
    return $this->view->render('admin/pages/users/user', $context);
44
  }
45
46
  public function formatUsers($users)
47
  {
48
    $users_for_list = [];
49
50
    foreach ($users as $user) {
51
      $user->new = $this->isUserNew($user->registration);
52
      $user->country_icon = $this->countries($user->country);
53
      $user->registration = $this->changeFormatDate($user->registration);
54
      $user->last_login = $this->changeFormatDate($user->last_login);
55
56
      $users_for_list[] = $user;
57
    }
58
    return $users_for_list;
59
  }
60
61
  public function filter()
62
  {
63
    $msg = null;
64
    $gets = $this->request->gets();
65
66
    if (empty($gets)) {
67
      $users = $this->load->model('User')->users();
68
69
      $usersformatted = $this->formatUsers($users);
70
      return json_encode($usersformatted);
71
    }
72
73
    $gender = $gets['gender'] ?? null;
74
    $zip = $gets['zip'] ?? null;
75
    $country = $gets['country'] ?? null;
76
    $registration_from = $gets['registration_from'] ?? null;
77
    $registration_to = $gets['registration_to'] ?? null;
78
    $active = $gets['active'] ?? null;
79
    $pending = $gets['pending'] ?? null;
80
    $inactive = $gets['inactive'] ?? null;
81
    $online = $gets['online'] ?? null;
82
    $offline = $gets['offline'] ?? null;
83
84
    $sql = '';
85
    $wheres = [];
86
87
    if ($active && $active == '1') {
88
      $sql .= 'status = ? AND ';
89
      array_push($wheres, '2');
90
    }
91
    if ($pending && $pending == '1') {
92
      $sql .= 'status = ? AND ';
93
      array_push($wheres, '1');
94
    }
95
    if ($inactive && $inactive == '1') {
96
      $sql .= 'status = ? AND ';
97
      array_push($wheres, '0');
98
    }
99
100
    $count_status = substr_count($sql, 'status = ?');
101
102
    if ($count_status > 1) {
103
      $sql = str_replace('status = ? AND', 'status = ? OR', $sql);
104
      $sql = rtrim($sql, 'OR ');
105
      $sql = "( $sql )";
106
      $sql .= ' AND ';
107
    }
108
109
    if ($online && $online == '1') {
110
      $sql .= 'is_login = ? AND ';
111
      array_push($wheres, '1');
112
    }
113
    if ($offline && $offline == '1') {
114
      $sql .= 'is_login = ? AND ';
115
      array_push($wheres, '0');
116
    }
117
118
    $count_is_login = substr_count($sql, 'is_login = ?');
119
120
    if ($count_is_login > 1) {
121
      $sql = str_replace('is_login = ? AND', 'is_login = ? OR', $sql);
122
      $sql = rtrim($sql, 'OR ');
123
      $sql = "( $sql )";
124
      $sql .= ' AND ';
125
    }
126
127
    if ($gender) {
128
      $sql .= 'gender = ? AND ';
129
      array_push($wheres, $gender);
130
    }
131
    if ($zip) {
132
      $sql .= 'zip = ? AND ';
133
      array_push($wheres, $zip);
134
    }
135
    if ($country) {
136
      $sql .= 'country = ? AND ';
137
      array_push($wheres, $country);
138
    }
139
140
    if ($registration_from) {
141
      $registration_from = date("Y-m-d", strtotime($registration_from));
142
143
      if (!$registration_to) {
144
        $sql .= 'registration >= ? AND ';
145
        array_push($wheres, $registration_from);
146
      } else {
147
        $registration_to = date("Y-m-d", strtotime($registration_to));
148
149
        $sql .= 'registration BETWEEN ? AND ? AND ';
150
        array_push($wheres, $registration_from);
151
        array_push($wheres, $registration_to);
152
      }
153
    }
154
155
    if ($sql == '') {
156
      $users = $this->load->model('User')->users();
157
158
      $usersformatted = $this->formatUsers($users);
159
160
      return json_encode($usersformatted);
161
    }
162
163
    $sql = substr($sql, 0, -4);
164
165
    $users = $this->load->model('User')->filter($sql, $wheres);
166
167
    if (!$users) {
168
      $msg = 'no users';
169
      return json_encode($msg);
170
    }
171
172
    $users_for_list = [];
173
174
    foreach ($users as $user) {
175
      $user->new = $this->isUserNew($user->registration);
176
      $user->country_icon = $this->countries($user->country);
177
      $user->registration = $this->changeFormatDate($user->registration);
178
      $user->last_login = $this->changeFormatDate($user->last_login);
179
180
      $users_for_list[] = $user;
181
    }
182
183
    $msg = $users_for_list;
184
    return json_encode($msg);
185
  }
186
187
  public function update()
188
  {
189
    $msg = null;
190
    $id = userId();
191
192
    if (!$this->isUserNotFound($id)) {
193
      $msg = 'reload';
194
      return json_encode($msg);
195
    }
196
    $posts = $this->request->posts();
197
    $name = array_keys($posts)[0];
198
    $allows = $this->file->call('config/admin/users/pages/update.php');
199
200
    if (!in_array($name, $allows)) {
201
      $msg = 'reload';
202
      return json_encode($msg);
203
    }
204
    $columns = $this->file->fileContent('config/admin/users/columns.json');
205
    $columns = json_decode($columns);
206
    $table = $columns->$name->table;
207
    $column = $columns->$name;
208
    $filters = $columns->$name->filters;
209
    $value = ($posts[$name] == '') ? null : isset($filters->date) ? date('Y-m-d', strtotime($posts[$name])) : $posts[$name];
210
    $user_id_table_name = $column->user_id_table_name;
211
212
    if ($this->isValuesAreTheSame($name, $table, $user_id_table_name, $id, $value)) {
213
      $msg['same'] = $value ? strtolower($value) : '';
214
      return json_encode($msg);
215
    }
216
    if ($this->validatorFails($filters, $name)) {
217
      $msg['error'] = $this->validator->getErrors();
218
      return json_encode($msg);
219
    }
220
    if (!$this->updateUser($name, $value, $user_id_table_name, $id, $table)) {
221
      $msg = 'reload';
222
      return json_encode($msg);
223
    }
224
    $msg = $this->userUpdateMsg($name, $value, $filters);
225
    return json_encode($msg);
226
  }
227
228
  private function userUpdateMsg($name, $value, $filters)
229
  {
230
    if ($name === 'country') {
231
      $msg['country'] = [
0 ignored issues
show
Comprehensibility Best Practice introduced by
$msg was never initialized. Although not strictly required by PHP, it is generally a good practice to add $msg = array(); before regardless.
Loading history...
232
        $value => $this->countries($value),
233
      ];
234
    } else {
235
      $msg['text'] = isset($filters->date) ? $this->changeFormatDate($value, ['Y-m-d', 'd M Y']) : _e($value);
236
    }
237
    return $msg;
238
  }
239
240
  private function updateUser($name, $value, $user_id_table_name, $id, $table)
241
  {
242
    return $this->db->data($name, $value)->where($user_id_table_name . ' = ?', $id)->update($table);
243
  }
244
245
  private function isUserNotFound($id)
246
  {
247
    return $this->load->model('User')->get($id);
248
  }
249
250
  private function isValuesAreTheSame($name, $table, $user_id_table_name, $id, $value)
251
  {
252
    $current_value = $this->db->select($name)->from($table)->where($user_id_table_name . ' = ?', [$id])->fetch()->$name;
253
    if (($current_value === strtolower($value)) || ($value == null && $current_value == null)) {
254
      return true;
255
    }
256
    return false;
257
  }
258
259
  private function validatorFails($filters, $name)
260
  {
261
    foreach ($filters as $func => $arg) {
262
      if (method_exists($this->validator, $func) == 1) {
263
        if (gettype($arg) === 'boolean') {
264
          if ($arg) {
265
            $this->validator->input($name)->$func();
266
          }
267
        } else {
268
          $this->validator->input($name)->$func($arg);
269
        }
270
      }
271
    }
272
    return $this->validator->fails();
273
  }
274
275
  public function new()
276
  {
277
    $countries = $this->countries('all', 'name');
278
    $context = [
279
      'countries' => $countries,
280
    ];
281
    return $this->view->render('admin/pages/users/new', $context);
282
  }
283
284
  public function add()
285
  {
286
    $msg = null;
287
    $posts = $this->request->posts();
288
    $names = array_keys($posts);
289
    $allows = $this->file->call('config/admin/users/pages/add.php');
290
291
    if (!array_equal($names, $allows)) {
292
      $msg = 'reload';
293
      return json_encode($msg);
294
    }
295
296
    $columns = $this->file->fileContent('config/admin/users/columns.json');
297
    $columns = json_decode($columns);
298
    $table = $this->load->model('User')->getTable();
299
300
    foreach ($names as $name) {
301
      $filters = $columns->$name->filters;
302
303
      foreach ($filters as $func => $arg) {
304
        if (method_exists($this->validator, $func) == 1) {
305
          if (gettype($arg) === 'boolean') {
306
            if ($arg) {
307
              $this->validator->input($name)->$func();
308
            }
309
          } else {
310
            $this->validator->input($name)->$func($arg);
311
          }
312
        }
313
      }
314
    }
315
316
    if ($this->validator->fails()) {
317
      $msg = $this->validator->getErrors();
318
      return json_encode($msg);
319
    }
320
321
    $factory = new Factory;
322
323
    $user_id = $factory->getMediumStrengthGenerator()->generateString(8, '0123456789');
324
    $code = $factory->getMediumStrengthGenerator()->generateString(20, '0123456789abcdefghijklmnopqrstuvwxyz');
325
    $username = $posts['username'];
326
    $fname = $posts['fname'];
327
    $lname = $posts['lname'];
328
    $gender = $posts['gender'];
329
    $birthday = date('Y-m-d', strtotime($posts['birthday']));
330
    $email = $posts['email'];
331
    $registration = $this->changeFormatDate(microtime(true), ['U.u', 'Y-m-d H:i:s']);
332
333
    $insertInUser = $this->db->data([
334
      'id' => $user_id,
335
      'code' => $code,
336
      'username' => $username,
337
      'fname' => $fname,
338
      'lname' => $lname,
339
      'gender' => $gender,
340
      'birthday' => $birthday,
341
      'email' => $email,
342
      'registration' => $registration,
343
    ])->insert($table);
344
345
    if (!$insertInUser) {
346
      $msg = 'reload';
347
      return json_encode($msg);
348
    }
349
350
    $country = $posts['country'] ? $posts['country'] : null;
351
    $state = $posts['state'] ? $posts['state'] : null;
352
    $city = $posts['city'] ? $posts['city'] : null;
353
    $zip = $posts['zip'] ? $posts['zip'] : null;
354
    $street = $posts['street'] ? $posts['street'] : null;
355
    $house_number = $posts['house_number'] ? $posts['house_number'] : null;
356
    $additional = $posts['additional'] ? $posts['additional'] : null;
357
358
    $insertInAddress = $this->db->data([
359
      'user_id' => $user_id,
360
      'country' => $country,
361
      'state' => $state,
362
      'city' => $city,
363
      'zip' => $zip,
364
      'street' => $street,
365
      'house_number' => $house_number,
366
      'additional' => $additional,
367
    ])->insert('address');
368
369
    $insertInActivity = $this->db->data([
370
      'user_id' => $user_id,
371
      'is_login' => 0,
372
    ])->insert('activity');
373
374
    if (!$insertInAddress || !$insertInActivity) {
375
      $msg = 'reload';
376
      return json_encode($msg);
377
    }
378
    $msg['success'] = $user_id;
379
    return json_encode($msg);
380
  }
381
382
  private function isUserNew($date)
383
  {
384
    if (!$date) {
385
      return;
386
    }
387
388
    $register_year = $this->changeFormatDate($date, ['Y-m-d H:i:s', 'Y']);
389
    $register_month = $this->changeFormatDate($date, ['Y-m-d H:i:s', 'm']);
390
    $register_day = $this->changeFormatDate($date, ['Y-m-d H:i:s', 'd']);
391
392
    $year = date('Y');
393
    $month = date('m');
394
    $day = date('d');
395
396
    $years = $year - $register_year;
397
398
    if ($years === 0) {
399
      $months = $month - $register_month;
400
401
      if ($months === 0) {
402
        $days = $day - $register_day;
403
404
        if ($days < 1) {
405
          return 1;
406
        }
407
      }
408
    }
409
    return 0;
410
  }
411
}
412