Completed
Push — work-fleets ( e04805...964a94 )
by SuperNova.WS
05:41
created

core_auth   F

Complexity

Total Complexity 121

Size/Duplication

Total Lines 834
Duplicated Lines 3.12 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 0%

Importance

Changes 9
Bugs 1 Features 0
Metric Value
c 9
b 1
f 0
dl 26
loc 834
rs 3.9999
ccs 0
cts 371
cp 0
wmc 121
lcom 1
cbo 11

21 Methods

Rating   Name   Duplication   Size   Complexity  
A __assign_vars() 0 7 1
A __construct() 0 14 2
C player_register_model() 0 52 11
B player_register_view() 6 36 5
F login() 0 94 25
B logout() 0 19 6
B impersonate() 0 30 5
B password_check() 0 16 5
B password_change() 0 40 6
A auth_reset() 0 10 1
C register_player_db_create() 0 56 12
A get_accessible_user_list() 0 19 3
C get_active_user() 0 33 8
C make_return_array() 0 59 9
B register_player_name_validate() 0 25 5
A make_password_reset_code() 0 3 1
A make_random_password() 0 3 1
A password_encode() 0 3 1
A password_salt_generate() 0 5 1
A cookie_set() 0 3 3
B flog() 20 20 10

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like core_auth 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 core_auth, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
// define("DEBUG_AUTH", true);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
4
5
/**
6
 * Статический над-класс, который обеспечивает интерфейс авторизации для остального кода
7
 *
8
 * User: Gorlum
9
 * Date: 21.04.2015
10
 * Time: 3:51
11
 *
12
 * version #41a7.59#
13
 */
14
class core_auth extends sn_module {
15
  public $manifest = array(
16
    'package'       => 'core',
17
    'name'          => 'auth',
18
    'version'       => '0a0',
19
    'copyright'     => 'Project "SuperNova.WS" #41a7.59# copyright © 2009-2015 Gorlum',
20
21
//    'require' => null,
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
22
    'root_relative' => '',
23
24
    'load_order' => 1,
25
26
    'installed' => true,
27
    'active'    => true,
28
29
    'mvc' => array(
30
      'model' => array(
31
        'player_register' => array(
32
          'callable' => 'player_register_model',
33
        ),
34
      ),
35
36
      'view' => array(
37
        'player_register' => array(
38
          'callable' => 'player_register_view',
39
        ),
40
      ),
41
    ),
42
  );
43
44
  /**
45
   * БД из которой читать данные
46
   *
47
   * @var db_mysql $db
48
   */
49
  public static $db;
50
  /**
51
   * Информация об устройстве
52
   *
53
   * @var RequestInfo
54
   */
55
  public static $device;
56
  /**
57
   * Аккаунт ????
58
   *
59
   * @var Account
60
   */
61
  public $account = null;
62
  /**
63
   * Запись текущего игрока из `users`
64
   *
65
   * @var array|bool|null
66
   */
67
  public static $user = null;
68
69
  /**
70
   * Основной провайдер
71
   *
72
   * @var auth_local
73
   */
74
  public static $main_provider = null;
75
76
  /**
77
   * Статус инициализации
78
   *
79
   * @var bool
80
   */
81
  // protected static $is_init = false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
82
  /**
83
   * Список провайдеров
84
   *
85
   * @var auth_local[]
86
   */
87
  protected $providers = array();
88
89
  /**
90
   * Глобальный статус входа в игру
91
   *
92
   * @var int
93
   */
94
  public static $login_status = LOGIN_UNDEFINED;
95
  /**
96
   * Имя, предлагаемое пользователю в качестве имени игрока
97
   *
98
   * @var string
99
   */
100
  protected $player_suggested_name = '';
101
102
  /**
103
   * Список полностью авторизированных аккаунтов с LOGIN_SUCCESS
104
   *
105
   * @var auth_local[]
106
   */
107
  protected $providers_authorised = array();
108
  /**
109
   * Статусы всех провайдеров
110
   *
111
   * @var auth_local[]
112
   */
113
  protected $provider_error_list = array();
114
  /**
115
   * Список юзеров (user_row - записей из `user`), доступных всем авторизированным аккаунтам
116
   *
117
   * @var array
118
   */
119
  protected $accessible_user_row_list = array();
120
121
  protected $user_id_to_provider = array();
122
123
  /**
124
   * Флаг имперсонации
125
   *
126
   * @var bool
127
   */
128
  protected $is_impersonating = false;
129
  protected $impersonator_username = '';
130
131
  /**
132
   * Флаг регистрации пользователя
133
   *
134
   * @var bool
135
   */
136
  protected $is_player_register = false;
137
  /**
138
   * @var int
139
   */
140
  protected $register_status = LOGIN_UNDEFINED;
141
142
  /**
143
   * Максимальный локальный уровень авторизации игрока
144
   *
145
   * @var int
146
   */
147
  public $auth_level_max_local = AUTH_LEVEL_ANONYMOUS;
148
149
  /**
150
   * @var int
151
   */
152
  public $partner_id = 0;
153
154
  /**
155
   * @var string
156
   */
157
  protected $server_name = '';
158
159
  /**
160
   * Присвоение переменных, которые нуждаются в позднем связывании - например, используют константы из манифеста
161
   * или еще не обрабатываются стандартной процедурой инициализациии модуля
162
   *
163
   * @return array
164
   */
165
  // OK 4.7
166
  public function __assign_vars() {
167
    return array(
168
      'sn_data[pages]' => array(
169
        'player_register' => 'includes/classes/core_auth',
170
      ),
171
    );
172
  }
173
174
  /**
175
   * @param string $filename
176
   */
177
  // TODO - OK 4.7
178
  public function __construct($filename = __FILE__) {
179
    parent::__construct($filename);
180
181
    self::$main_provider = new auth_local();
182
183
    // В этой точке все модули уже прогружены и инициализированы по 1 экземпляру
184
    // self::$db = !is_object($db) ? classSupernova::$db : $db;
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
185
    self::$db = classSupernova::$db;
186
187
    self::$device = new RequestInfo();
188
    $this->is_player_register = sys_get_param('player_register') ? true : false;
189
    $this->partner_id = sys_get_param_int('id_ref', sys_get_param_int('partner_id'));
190
    $this->server_name = sys_get_param_str_unsafe('server_name', SN_ROOT_VIRTUAL);
191
  }
192
193
  // TODO - OK v4.7
194
  public function player_register_model() {
195
    // TODO ВСЕГДА ПРЕДЛАГАТЬ РЕГАТЬ ИГРОКА ИЛИ ПОДКЛЮЧИТЬ ИМЕЮЩЕГОСЯ!
196
197
    // TODO в auth_local делать проверку БД на существование имени игрока в локальной БД - что бы избежать лишнего шага (см.выше)
198
    // TODO Хотя тут может получится вечный цикл - ПОДУМАТЬ
199
    // TODO Тут же можно пробовать провести попытку слияния аккаунтов - хотя это и очень небезопасно
200
201
    if (sys_get_param('login_player_register_logout')) {
202
      $this->logout();
203
    }
204
205
    $original_suggest = '';
206
    // Смотрим - есть ли у нас данные от пользователя
207
    if (($player_name_submitted = sys_get_param('submit_player_name'))) {
208
      // Попытка регистрации нового игрока из данных, введенных пользователем
209
      $this->player_suggested_name = sys_get_param_str_unsafe('player_suggested_name');
210
    } else {
211
      foreach ($this->providers_authorised as $provider) {
212
        if ($this->player_suggested_name = $provider->player_name_suggest()) { // OK 4.5
213
          $original_suggest = $provider->player_name_suggest();
214
          break;
215
        }
216
      }
217
    }
218
219
    // Если у нас провайдеры не дают имени и пользователь не дал свой вариант - это у нас первый логин в игру
220
    if (!$this->player_suggested_name) {
221
      $max_user_id = DBStaticUser::getMaxId(); // 4.5
222
      // TODO - предлагать имя игрока по локали
223
224
      // Проверить наличие такого имени в истории имён
225
      do {
226
        sn_db_transaction_rollback();
227
        $this->player_suggested_name = 'Emperor ' . mt_rand($max_user_id + 1, $max_user_id + 1000);
228
        sn_db_transaction_start();
229
      } while (db_player_name_exists($this->player_suggested_name));
230
231
    }
232
233
    if ($player_name_submitted) {
234
      $this->register_player_db_create($this->player_suggested_name); // OK 4.5
235
      if ($this->register_status == LOGIN_SUCCESS) {
236
        sys_redirect(SN_ROOT_VIRTUAL . 'overview.php');
237
      } elseif ($this->register_status == REGISTER_ERROR_PLAYER_NAME_EXISTS && $original_suggest == $this->player_suggested_name) {
0 ignored issues
show
Unused Code introduced by
This elseif statement is empty, and could be removed.

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

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

Loading history...
238
        // self::$player_suggested_name .= ' ' . $this->account->account_id;
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
239
      }
240
//      if(self::$login_status != LOGIN_SUCCESS) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
241
//        // TODO Ошибка при регистрации нового игрока под текущим именем
242
//      }
243
    }
244
245
  }
246
247
  // TODO - OK v4.7
248
  public function player_register_view($template = null) {
249
    global $template_result;
250
251
    define('LOGIN_LOGOUT', true);
252
253
    $template_result[F_PLAYER_REGISTER_MESSAGE] =
254
      isset($template_result[F_PLAYER_REGISTER_MESSAGE]) && $template_result[F_PLAYER_REGISTER_MESSAGE]
255
        ? $template_result[F_PLAYER_REGISTER_MESSAGE]
256
        : ($this->register_status != LOGIN_UNDEFINED
257
        ? classLocale::$lang['sys_login_messages'][$this->register_status]
258
        : false
259
      );
260
261 View Code Duplication
    if ($this->register_status == LOGIN_ERROR_USERNAME_RESTRICTED_CHARACTERS) {
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...
262
      $prohibited_characters = array_map(function ($value) {
263
        return "'" . htmlentities($value, ENT_QUOTES, 'UTF-8') . "'";
264
      }, str_split(LOGIN_REGISTER_CHARACTERS_PROHIBITED));
265
      $template_result[F_PLAYER_REGISTER_MESSAGE] .= implode(', ', $prohibited_characters);
266
    }
267
268
//    pdump('view');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
269
//    die('view');
270
    $template_result = array_merge($template_result, array(
271
      'NAVBAR'                  => false,
272
      'PLAYER_SUGGESTED_NAME'   => sys_safe_output($this->player_suggested_name),
273
      'PARTNER_ID'              => sys_safe_output($this->partner_id),
274
      'SERVER_NAME'             => sys_safe_output($this->server_name),
275
      'PLAYER_REGISTER_STATUS'  => $this->register_status,
276
      'PLAYER_REGISTER_MESSAGE' => $template_result[F_PLAYER_REGISTER_MESSAGE],
277
      'LOGIN_UNDEFINED'         => LOGIN_UNDEFINED,
278
    ));
279
280
    $template = gettemplate('login_player_register', $template);
281
282
    return $template;
283
  }
284
285
  /**
286
   * Функция пытается залогиниться по всем известным провайдерам
287
   *
288
   * @param null $result
0 ignored issues
show
Bug introduced by
There is no parameter named $result. Was it maybe removed?

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

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

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

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

Loading history...
289
   */
290
  public function login() {
291
    if (empty(sn_module::$sn_module_list['auth'])) {
292
      die('{Не обнаружено ни одного провайдера авторизации в core_auth::login()!}');
293
    }
294
295
    !empty($_POST) ? self::flog(dump($_POST, '$_POST')) : false;
296
    !empty($_GET) ? self::flog(dump($_GET, '$_GET')) : false;
297
    !empty($_COOKIE) ? self::flog(dump($_COOKIE, '$_COOKIE')) : false;
298
299
    $this->auth_reset(); // OK v4.5
300
301
    $this->providers = array();
302
    foreach (sn_module::$sn_module_list['auth'] as $module_name => $module) {
303
      $this->providers[$module->provider_id] = $module;
304
    }
305
306
    // $this->providers = array_reverse($this->providers, true); // НИНАДА! СН-аккаунт должен всегда авторизироваться первым!
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
307
308
    foreach ($this->providers as $provider_id => $provider) {
309
      $login_status = $provider->login(); // OK v4.5
310
      self::flog(($provider->manifest['name'] . '->' . 'login_try - ') . (empty($provider->account->account_id) ? classLocale::$lang['sys_login_messages'][$provider->account_login_status] : dump($provider)));
311
      if ($login_status == LOGIN_SUCCESS && is_object($provider->account) && $provider->account instanceof Account && $provider->account->account_id) {
312
        $this->providers_authorised[$provider_id] = &$this->providers[$provider_id];
313
314
        $this->user_id_to_provider = array_replace_recursive(
315
          $this->user_id_to_provider,
316
          // static::db_translate_get_users_from_account_list($provider_id, $provider->account->account_id) // OK 4.5
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
317
          PlayerToAccountTranslate::db_translate_get_users_from_account_list($provider_id, $provider->account->account_id) // OK 4.5
318
        );
319
      } elseif ($login_status != LOGIN_UNDEFINED) {
320
        $this->provider_error_list[$provider_id] = $login_status;
321
      }
322
    }
323
324
    if (empty($this->providers_authorised)) {
325
      // Ни один аккаунт не авторизирован
326
      // Проверяем - есть ли у нас ошибки в аккаунтах?
327
      if (!empty($this->provider_error_list)) {
328
        // Если есть - выводим их
329
        self::$login_status = reset($this->provider_error_list);
330
      }
331
      // Иначе - это первый запуск страницы. ИЛИ СПЕЦИАЛЬНОЕ ДЕЙСТВИЕ!
332
      // ...которые по факты должны обрабатываться в рамках provider->login()
333
    } else {
334
      // Есть хотя бы один авторизированный аккаунт
335
      $temp = reset($this->providers_authorised);
336
      $this->account = $temp->account;
337
338
      $this->get_accessible_user_list();
339
      // В self::$accessible_user_row_list - список доступных игроков для данных аккаунтов с соответствующими записями из таблицы `users`
340
341
      // Остались ли у нас в списке доступные игроки?
342
      if (empty($this->accessible_user_row_list)) {
343
        // Нет ни одного игрока ни на одном авторизированном аккаунте
344
        // Надо регать нового игрока
345
346
        // Сейчас происходит процесс регистрации игрока?
347
        if (!$this->is_player_register) {
348
          // Нет - отправляем на процесс регистрации
349
          $partner_id = sys_get_param_int('id_ref', sys_get_param_int('partner_id'));
350
          sys_redirect(SN_ROOT_VIRTUAL . 'index.php?page=player_register&player_register=1' . ($partner_id ? '&id_ref=' . $partner_id : ''));
351
        }
352
      } else {
353
        // Да, есть доступные игроки, которые так же прописаны в базе
354
        $this->get_active_user(); // 4.5
355
356
        if ($this->is_impersonating = !empty($_COOKIE[SN_COOKIE_U_I]) ? $_COOKIE[SN_COOKIE_U_I] : 0) {
357
          $a_user = DBStaticUser::db_user_by_id($this->is_impersonating);
358
          $this->impersonator_username = $a_user['username'];
359
        }
360
361
362
        //Прописываем текущего игрока на все авторизированные аккаунты
363
        // TODO - ИЛИ ВСЕХ ИГРОКОВ??
364
        if (empty($this->is_impersonating)) {
365
          foreach ($this->providers_authorised as $provider_id => $provider) {
366
            if (empty($this->user_id_to_provider[self::$user['id']][$provider_id])) {
367
              // self::db_translate_register_user($provider_id, $provider->account->account_id, self::$user['id']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
368
              PlayerToAccountTranslate::db_translate_register_user($provider_id, $provider->account->account_id, self::$user['id']);
369
              $this->user_id_to_provider[self::$user['id']][$provider_id][$provider->account->account_id] = true;
370
            }
371
          }
372
        }
373
      }
374
    }
375
376
    if (empty(self::$user['id'])) {
377
      self::cookie_set(''); // OK 4.5
378
    } elseif (self::$user['id'] != $_COOKIE[SN_COOKIE_U]) {
379
      self::cookie_set(self::$user['id']); // OK 4.5
380
    }
381
382
    return $this->make_return_array();
383
  }
384
385
  /**
386
   * Логаут игрока и всех аккаунтов
387
   *
388
   * @param bool|string $redirect нужно ли сделать перенаправление после логаута
389
   * <p><b>false</b> - не перенаправлять</p>
390
   * <p><i><b>true</b></i> - перенаправить на главную страницу</p>
391
   * <p><b>string</b> - перенаправить на указанный URL</p>
392
   *
393
   * @param bool        $only_impersonator Если установлен - то логаут происходит только при имперсонации
394
   */
395
  // OK v4.7
396
  public function logout($redirect = true) {
397
    if (!empty($_COOKIE[SN_COOKIE_U_I])) {
398
      self::cookie_set($_COOKIE[SN_COOKIE_U_I]);
399
      self::cookie_set(0, true);
400
      self::$main_provider->logout();
401
    } else {
402
      foreach ($this->providers as $provider_name => $provider) {
403
        $provider->logout();
404
      }
405
406
      self::cookie_set(0);
407
    }
408
409
    if ($redirect === true) {
410
      sys_redirect(SN_ROOT_RELATIVE . (empty($_COOKIE[SN_COOKIE_U]) ? 'login.php' : 'admin/overview.php'));
411
    } elseif ($redirect !== false) {
412
      sys_redirect($redirect);
413
    }
414
  }
415
416
  /**
417
   * Имперсонация
418
   *
419
   * @param $user_selected
420
   */
421
  public function impersonate($user_selected) {
422
    if ($_COOKIE[SN_COOKIE_U_I]) {
423
      die('You already impersonating someone. Go back to living other\'s life! Or clear your cookies and try again'); // TODO: Log it
424
    }
425
426
    if ($this->auth_level_max_local < AUTH_LEVEL_ADMINISTRATOR) {
427
      die('You can\'t impersonate - too low level'); // TODO: Log it
428
    }
429
430
    if ($this->auth_level_max_local <= $user_selected['authlevel']) {
431
      die('You can\'t impersonate this account - level is greater or equal to yours'); // TODO: Log it
432
    }
433
434
    $account_translate = PlayerToAccountTranslate::db_translate_get_account_by_user_id($user_selected['id'], self::$main_provider->provider_id);
435
    $account_translate = reset($account_translate[$user_selected['id']][self::$main_provider->provider_id]);
436
    $account_to_impersonate = new Account(self::$main_provider->db);
437
    $account_to_impersonate->db_get_by_id($account_translate['provider_account_id']);
438
    if (!$account_to_impersonate->is_exists) {
439
      die('Какая-то ошибка - не могу найти аккаунт для имперсонации'); // TODO: Log it
440
    }
441
    self::$main_provider->impersonate($account_to_impersonate);
442
443
    self::cookie_set($_COOKIE[SN_COOKIE_U], true, 0);
444
445
    // TODO - Имперсонейт - только на одну сессию
446
    self::cookie_set($user_selected['id']);
447
448
    // sec_set_cookie_by_user($user_selected, 0);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
449
    sys_redirect(SN_ROOT_RELATIVE);
450
  }
451
452
  /**
453
   * Проверяет пароль на совпадение с текущими паролями
454
   *
455
   * @param $password_unsafe
456
   *
457
   * @return bool
458
   */
459
  // OK v4.6
460
  // TODO - ПЕРЕДЕЛАТЬ!
461
  public function password_check($password_unsafe) {
462
    $result = false;
463
464
    if (empty($this->providers_authorised)) {
465
      // TODO - такого быть не может!
466
      self::flog("password_check: Не найдено ни одного авторизированного провайдера в self::\$providers_authorised", true);
467
    } else {
468
      foreach ($this->providers_authorised as $provider_id => $provider) {
469
        if ($provider->is_feature_supported(AUTH_FEATURE_HAS_PASSWORD)) {
470
          $result = $result || $provider->password_check($password_unsafe);
471
        }
472
      }
473
    }
474
475
    return $result;
476
  }
477
478
  /**
479
   * Меняет старый пароль на новый
480
   *
481
   * @param $old_password_unsafe
482
   * @param $new_password_unsafe
483
   *
484
   * @return bool
485
   */
486
  // OK v4.6
487
  public function password_change($old_password_unsafe, $new_password_unsafe) {
488
    if (empty($this->providers_authorised)) {
489
      // TODO - такого быть не может!
490
      self::flog("Не найдено ни одного авторизированного провайдера в self::\$providers_authorised", true);
491
492
      return false;
493
    }
494
495
    // TODO - Проверять пароль на корректность
496
497
    // TODO - Не менять (?) пароль у аккаунтов, к которым пристёгнут хоть один игрок с AUTH_LEVEL > 0
498
499
    $salt_unsafe = self::password_salt_generate();
500
501
    $providers_changed_password = array();
502
    foreach ($this->providers_authorised as $provider_id => $provider) {
503
      if (
504
        !$provider->is_feature_supported(AUTH_FEATURE_PASSWORD_CHANGE)
505
        || !$provider->password_change($old_password_unsafe, $new_password_unsafe, $salt_unsafe)
506
      ) {
507
        continue;
508
      }
509
510
      // Узнаем список игроков, которые прикреплены к этому аккаунту
511
      // $account_translation = self::db_translate_get_users_from_account_list($provider_id, $provider->account->account_id);
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
512
      $account_translation = PlayerToAccountTranslate::db_translate_get_users_from_account_list($provider_id, $provider->account->account_id);
513
514
      // Рассылаем уведомления о смене пароля в ЛС
515
      foreach ($account_translation as $user_id => $provider_info) {
516
        // TODO - УКазывать тип аккаунта, на котором сменён пароль
517
        $message = sprintf(classLocale::$lang['sys_login_register_message_body'], $provider->account->account_name, $new_password_unsafe);
518
        DBStaticMessages::msgSendFromAdmin($user_id, classLocale::$lang['sys_login_register_message_title'], $message);
519
      }
520
      $providers_changed_password[$provider_id] = $provider;
521
    }
522
523
    // TODO - отсылать уведомление на емейл
524
525
    return !empty($providers_changed_password);
526
  }
527
528
529
530
531
  /**
532
   * Сбрасывает значения полей
533
   */
534
  // OK v4.5
535
  protected function auth_reset() {
536
    self::$login_status = LOGIN_UNDEFINED;
537
    $this->player_suggested_name = '';
538
    $this->account = null;
539
    self::$user = null;
540
    $this->providers_authorised = array(); // Все аккаунты, которые успешно залогинились
541
    $this->provider_error_list = array(); // Статусы всех аккаунтов
542
    $this->accessible_user_row_list = array();
543
    $this->user_id_to_provider = array();
544
  }
545
546
  /**
547
   * Функция пытается создать игрока в БД, делая все нужные проверки
548
   *
549
   * @param $player_name_unsafe
550
   */
551
  // OK v4
552
  protected function register_player_db_create($player_name_unsafe) {
553
    try {
554
      // Проверить корректность имени
555
      $this->register_player_name_validate($player_name_unsafe);
556
557
      sn_db_transaction_start();
558
      // Проверить наличие такого имени в истории имён
559
560
      if (db_player_name_exists($player_name_unsafe)) {
561
        throw new Exception(REGISTER_ERROR_PLAYER_NAME_EXISTS, ERR_ERROR);
562
      }
563
564
      // Узнаем язык и емейл игрока
565
      $player_language = '';
566
      $player_email = '';
567
      // TODO - порнография - работа должна происходить над списком аккаунтов, а не только на одном аккаунте...
568
      foreach ($this->providers_authorised as $provider) {
569
        if (!$player_language && $provider->account->account_language) {
570
          $player_language = $provider->account->account_language;
571
        }
572
        if (!$player_email && $provider->account->account_email) {
573
          $player_email = $provider->account->account_email;
574
        }
575
      }
576
      $player_language = sys_get_param_str('lang') ? sys_get_param_str('lang') : $player_language;
577
      $player_language = $player_language ? $player_language : DEFAULT_LANG;
578
579
      // TODO - дописать эксепшнов в процедуре создания игрока
580
      self::$user = player_create($player_name_unsafe, $player_email, array(
581
        'partner_id'   => $partner_id = sys_get_param_int('id_ref', sys_get_param_int('partner_id')),
582
        'language_iso' => static::$db->db_escape($player_language),
583
        // 'password_encoded_unsafe' => $this->data[F_ACCOUNT]['account_password'],
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
584
        // 'salt' => $this->data[F_ACCOUNT]['account_salt'],
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
585
      ));
586
      // Зарегестрировать на него аккаунты из self::$accounts_authorised
587
      $a_user = self::$user;
588
      foreach ($this->providers_authorised as $provider) {
589
        // TODO - порнография. Должен быть отдельный класс трансляторов - в т.ч. и кэширующий транслятор
590
        // TODO - ну и работа должна происходить над списком аккаунтов, а не только на одном аккаунте...
591
        // self::db_translate_register_user($provider->provider_id, $provider->account->account_id, $a_user['id']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
592
        PlayerToAccountTranslate::db_translate_register_user($provider->provider_id, $provider->account->account_id, $a_user['id']);
593
594
      }
595
      // Установить куку игрока
596
      self::cookie_set(self::$user['id']);
597
598
      sn_db_transaction_commit();
599
      $this->register_status = LOGIN_SUCCESS;
600
    } catch (Exception $e) {
601
      sn_db_transaction_rollback();
602
603
      // Если старое имя занято
604
      self::$user = null;
605
      $this->register_status == LOGIN_UNDEFINED ? $this->register_status = $e->getMessage() : false;
0 ignored issues
show
Documentation Bug introduced by
The property $register_status was declared of type integer, but $e->getMessage() is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
606
    }
607
  }
608
609
610
  /**
611
   * Проверяет доступ авторизированных аккаунтов к заявленным в трансляции юзерам
612
   * @version 4.5
613
   */
614
  // OK v4.5
615
  protected function get_accessible_user_list() {
616
    // Пробиваем все ИД игроков по базе - есть ли вообще такие записи
617
    // Вообще-то это не особо нужно - у нас по определению стоят констраинты
618
    // Зато так мы узнаем максимальный authlevel, проверим права имперсонейта и вытащим все записи юзеров
619
    foreach ($this->user_id_to_provider as $user_id => $cork) {
620
      $user = DBStaticUser::db_user_by_id($user_id);
621
      // Если записи игрока в БД не существует?
622
      if (empty($user['id'])) {
623
        // Удаляем этого и переходим к следующему
624
        unset($this->user_id_to_provider[$user_id]);
625
        // Де-регистрируем игрока из таблицы трансляции игроков
626
        PlayerToAccountTranslate::db_translate_unregister_user($user_id);
627
      } else {
628
        $this->accessible_user_row_list[$user['id']] = $user;
629
        $this->auth_level_max_local = max($this->auth_level_max_local, $user['authlevel']);
630
      }
631
      unset($user);
632
    }
633
  }
634
635
  /**
636
   * Выбирает активного игрока из куки или из списка доступных игроков
637
   *
638
   * @version 4.5
639
   */
640
  // OK v4.5
641
  protected function get_active_user() {
642
    // Проверяем куку "текущего игрока" из браузера
643
    if (
644
      // Кука не пустая
645
      ($_COOKIE[SN_COOKIE_U] = trim($_COOKIE[SN_COOKIE_U])) && !empty($_COOKIE[SN_COOKIE_U])
646
      // И в куке находится ID
647
      && is_id($_COOKIE[SN_COOKIE_U])
648
      // И у аккаунтов есть права на данного игрока
649
      && (
650
        // Есть прямые права из `account_translate`
651
        !empty($this->accessible_user_row_list[$_COOKIE[SN_COOKIE_U]])
652
        // Или есть доступ через имперсонейт
653
        || (
654
          // Максимальные права всех доступных записей игроков - не ниже администраторских
655
          $this->auth_level_max_local >= AUTH_LEVEL_ADMINISTRATOR
656
          // И права игрока, в которого пытаются зайти - меньше текущих максимальных прав
657
          && $this->accessible_user_row_list[$_COOKIE[SN_COOKIE_U]]['authlevel'] < $this->auth_level_max_local
658
        )
659
      )
660
    ) {
661
      // Берем текущим юзером юзера с ИД из куки
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
662
//      $this->is_impersonating = empty($this->accessible_user_row_list[$_COOKIE[SN_COOKIE_U]]);
663
      // self::$user = self::$accessible_user_row_list[$_COOKIE[SN_COOKIE_U]];
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
664
      self::$user = DBStaticUser::db_user_by_id($_COOKIE[SN_COOKIE_U]);
665
    }
666
667
    // В куке нет валидного ИД записи игрока, доступной с текущих аккаунтов
668
    if (empty(self::$user['id'])) {
669
      // Берем первого из доступных
670
      // TODO - default_user
671
      self::$user = reset($this->accessible_user_row_list);
672
    }
673
  }
674
675
676
677
  /**
678
   * Генерирует набор даннх для возврата в основной код
679
   */
680
  // OK v4.5
681
  protected function make_return_array() {
682
    $user_id = !empty(self::$user['id']) ? self::$user['id'] : 0;
683
    // if(!empty($user_id) && !$user_impersonator) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
684
    // $user_id не может быть пустым из-за констраинтов в таблице SPE
685
    // self::db_security_entry_insert();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
686
    self::$device->db_security_entry_insert($user_id);
687
688
    $result = array();
689
690
    if ($user_id && empty($this->is_impersonating)) {
691
      // self::db_counter_insert();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
692
      self::$device->db_counter_insert($user_id);
693
694
      $user = &self::$user;
695
696
      sys_user_options_unpack($user);
697
698
      if ($user['banaday'] && $user['banaday'] <= SN_TIME_NOW) {
699
        $user['banaday'] = 0;
700
        $user['vacation'] = SN_TIME_NOW;
701
      }
702
703
      $user['user_lastip'] = self::$device->ip_v4_string;// $ip['ip'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
704
      $user['user_proxy'] = self::$device->ip_v4_proxy_chain; //$ip['proxy_chain'];
705
706
      $result[F_BANNED_STATUS] = $user['banaday'];
707
      $result[F_VACATION_STATUS] = $user['vacation'];
708
709
      $proxy_safe = static::$db->db_escape(self::$device->ip_v4_proxy_chain);
710
711
      DBStaticUser::db_user_set_by_id($user['id'], "`onlinetime` = " . SN_TIME_NOW . ",
712
      `banaday` = " . static::$db->db_escape($user['banaday']) . ", `vacation` = " . static::$db->db_escape($user['vacation']) . ",
713
      `user_lastip` = '" . static::$db->db_escape($user['user_lastip']) . "', `user_last_proxy` = '{$proxy_safe}', `user_last_browser_id` = " . self::$device->browser_id
714
      );
715
    }
716
717
    if ($extra = classSupernova::$config->security_ban_extra) {
718
      $extra = explode(',', $extra);
719
      array_walk($extra, 'trim');
720
      in_array(self::$device->device_id, $extra) and die();
721
    }
722
723
    $result[F_LOGIN_STATUS] = self::$login_status = empty($this->providers_authorised) ? self::$login_status : LOGIN_SUCCESS;
724
    $result[F_PLAYER_REGISTER_STATUS] = $this->register_status;
725
    $result[F_USER] = self::$user;
726
727
    // $result[AUTH_LEVEL] = isset(self::$user['authlevel']) ? self::$user['authlevel'] : AUTH_LEVEL_ANONYMOUS;
0 ignored issues
show
Unused Code Comprehensibility introduced by
68% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
728
    $result[AUTH_LEVEL] = $this->auth_level_max_local;
729
730
    $result[F_IMPERSONATE_STATUS] = $this->is_impersonating;
731
    $result[F_IMPERSONATE_OPERATOR] = $this->impersonator_username;
732
    // TODO
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
733
//    self::$hidden[F_IMPERSONATE_OPERATOR] = $found_provider->data[F_IMPERSONATE_OPERATOR];
734
735
    //TODO Сол и Парол тоже вкинуть в хидден
736
    $result[F_ACCOUNTS_AUTHORISED] = $this->providers_authorised;
737
738
    return $result;
739
  }
740
741
742
  // ХЕЛПЕРЫ ===========================================================================================================
743
  /**
744
   * Функция проверяет корректность имени игрока при регистрации
745
   *
746
   * @param $player_name_unsafe
747
   *
748
   * @throws Exception
749
   */
750
  // OK v4
751
  // TODO - вынести в отдельный хелпер
752
  protected function register_player_name_validate($player_name_unsafe) {
753
    // TODO - переделать под RAW-строки
754
    // Если имя игрока пустое - NO GO!
755
    if (trim($player_name_unsafe) == '') {
756
      throw new Exception(REGISTER_ERROR_PLAYER_NAME_EMPTY, ERR_ERROR);
757
    }
758
    // Проверяем, что бы в начале и конце не было пустых символов
759
    if ($player_name_unsafe != trim($player_name_unsafe)) {
760
      throw new Exception(REGISTER_ERROR_PLAYER_NAME_TRIMMED, ERR_ERROR);
761
    }
762
    // Если логин имеет запрещенные символы - NO GO!
763
    if (strpbrk($player_name_unsafe, LOGIN_REGISTER_CHARACTERS_PROHIBITED)) {
764
      // TODO - выдавать в сообщение об ошибке список запрещенных символов
765
      // TODO - заранее извещать игрока, какие символы являются запрещенными
766
      throw new Exception(REGISTER_ERROR_PLAYER_NAME_RESTRICTED_CHARACTERS, ERR_ERROR);
767
    }
768
    // Если логин меньше минимальной длины - NO GO!
769
    if (strlen($player_name_unsafe) < LOGIN_LENGTH_MIN) {
770
      // TODO - выдавать в сообщение об ошибке минимальную длину имени игрока
771
      // TODO - заранее извещать игрока, какая минимальная и максимальная длина имени
772
      throw new Exception(REGISTER_ERROR_PLAYER_NAME_SHORT, ERR_ERROR);
773
    }
774
775
    // TODO проверка на максимальную длину имени игрока
776
  }
777
778
  /**
779
   * Генерирует случайный код для сброса пароля
780
   *
781
   * @return string
782
   */
783
  // OK v4
784
  public static function make_password_reset_code() {
785
    return sys_random_string(LOGIN_PASSWORD_RESET_CONFIRMATION_LENGTH, SN_SYS_SEC_CHARS_CONFIRMATION);
786
  }
787
  /**
788
   * Генерирует случайный пароль
789
   *
790
   * @return string
791
   */
792
  // OK v4
793
  public static function make_random_password() {
794
    return sys_random_string(LOGIN_PASSWORD_RESET_CONFIRMATION_LENGTH, SN_SYS_SEC_CHARS_CONFIRMATION);
795
  }
796
  /**
797
   * Просаливает пароль
798
   *
799
   * @param $password
800
   * @param $salt
801
   *
802
   * @return string
803
   */
804
  // OK v4
805
  public static function password_encode($password, $salt) {
806
    return md5($password . $salt);
807
  }
808
  /**
809
   * Генерирует соль
810
   *
811
   * @return string
812
   */
813
  // OK v4
814
  public static function password_salt_generate() {
815
    // НЕ ПЕРЕКРЫВАТЬ
816
    // TODO ВКЛЮЧИТЬ ГЕНЕРАЦИЮ СОЛИ !!!
817
    return ''; // sys_random_string(16);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
818
  }
819
820
  // OK v4.5
821
  // TODO - REMEMBER_ME
822
  protected static function cookie_set($value, $impersonate = false, $period = null) {
823
    sn_setcookie($impersonate ? SN_COOKIE_U_I : SN_COOKIE_U, $value, $period === null ? SN_TIME_NOW + PERIOD_YEAR : $period, SN_ROOT_RELATIVE);
824
  }
825
826 View Code Duplication
  protected static function flog($message, $die = false) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
827
    if (!defined('DEBUG_AUTH') || !DEBUG_AUTH) {
828
      return;
829
    }
830
    list($called, $caller) = debug_backtrace(false);
831
    $caller_name =
832
      (!empty($caller['class']) ? $caller['class'] : '') .
833
      (!empty($caller['type']) ? $caller['type'] : '') .
834
      (!empty($caller['function']) ? $caller['function'] : '') .
835
      (!empty($called['line']) ? ':' . $called['line'] : '');
836
837
    $_SERVER['SERVER_NAME'] == 'localhost' ? print("<div class='debug'>$message - $caller_name\r\n</div>") : false;
838
839
    classSupernova::log_file("$message - $caller_name");
840
    if ($die) {
841
      // pdump($caller);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
842
      // pdump(debug_backtrace(false));
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
843
      $die && die("<div class='negative'>СТОП! Функция {$caller_name} при вызове в " . get_called_class() . " (располагается в " . get_class() . "). СООБЩИТЕ АДМИНИСТРАЦИИ!</div>");
844
    }
845
  }
846
847
}
848