Completed
Push — work-fleets ( b19a67...de8005 )
by SuperNova.WS
06:26
created

classSupernova::init_1_globalContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 49
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 1
eloc 21
nc 1
nop 0
dl 0
loc 49
rs 9.2258
c 3
b 0
f 0
ccs 0
cts 43
cp 0
crap 2
1
<?php
2
3
use Vector\Vector;
4
5
class classSupernova {
6
  /**
7
   * @var \Pimple\GlobalContainer $gc
8
   */
9
  public static $gc;
10
11
  /**
12
   * ex $sn_mvc
13
   *
14
   * @var array
15
   */
16
  public static $sn_mvc = array();
17
18
  /**
19
   * ex $functions
20
   *
21
   * @var array
22
   */
23
  public static $functions = array();
24
25
  /**
26
   * @var array[] $design
27
   */
28
  public static $design = array(
29
    'bbcodes' => array(),
30
    'smiles'  => array(),
31
  );
32
33
  /**
34
   * Основная БД для доступа к данным
35
   *
36
   * @var db_mysql $db
37
   */
38
  public static $db;
39
  public static $db_name = '';
40
41
  /**
42
   * @var SnCache $dbCache
43
   */
44
  public static $dbCache;
45
46
  /**
47
   * Настройки из файла конфигурации
48
   *
49
   * @var string
50
   */
51
  public static $cache_prefix = '';
52
53
  public static $sn_secret_word = '';
54
55
  /**
56
   * Конфигурация игры
57
   *
58
   * @var classConfig $config
59
   */
60
  public static $config;
61
62
63
  /**
64
   * Кэш игры
65
   *
66
   * @var classCache $cache
67
   */
68
  public static $cache;
69
70
71
  /**
72
   * @var core_auth $auth
73
   */
74
  public static $auth = null;
75
76
77
  public static $db_in_transaction = false;
78
  public static $db_records_locked = false;
79
  public static $transaction_id = 0;
80
  public static $user = array();
81
  /**
82
   * @var userOptions
83
   */
84
  public static $user_options;
85
86
  /**
87
   * @var debug $debug
88
   */
89
  public static $debug = null;
90
91
  public static $options = array();
92
93
  public static $delayed_changset = array(); // Накопительный массив изменений
94
95
  // Кэш индексов - ключ MD5-строка от суммы ключевых строк через | - менять | на что-то другое перед поиском и назад - после поиска
96
  // Так же в индексах могут быть двойные вхождения - например, названия планет да и вообще
97
  // Придумать спецсимвол для NULL
98
99
  /*
100
  TODO Кэш:
101
  1. Всегда дешевле использовать процессор, чем локальную память
102
  2. Всегда дешевле использовать локальную память, чем общую память всех процессов
103
  3. Всегда дешевле использовать общую память всех процессов, чем обращаться к БД
104
105
  Кэш - многоуровневый: локальная память-общая память-БД
106
  БД может быть сверхкэширующей - см. HyperNova. Это реализуется на уровне СН-драйвера БД
107
  Предусмотреть вариант, когда уровни кэширования совпадают, например когда нет xcache и используется общая память
108
  */
109
110
  // TODO Автоматически заполнять эту таблицу. В случае кэша в памяти - делать show table при обращении к таблице
111
  public static $location_info = array(
112
    LOC_USER => array(
113
      P_TABLE_NAME => 'users',
114
      P_ID         => 'id',
115
      P_OWNER_INFO => array(),
116
    ),
117
118
    LOC_PLANET => array(
119
      P_TABLE_NAME => 'planets',
120
      P_ID         => 'id',
121
      P_OWNER_INFO => array(
122
        LOC_USER => array(
123
          P_LOCATION    => LOC_USER,
124
          P_OWNER_FIELD => 'id_owner',
125
        ),
126
      ),
127
    ),
128
129
    LOC_UNIT => array(
130
      P_TABLE_NAME => 'unit',
131
      P_ID         => 'unit_id',
132
      P_OWNER_INFO => array(
133
        LOC_USER => array(
134
          P_LOCATION    => LOC_USER,
135
          P_OWNER_FIELD => 'unit_player_id',
136
        ),
137
      ),
138
    ),
139
140
    LOC_QUE => array(
141
      P_TABLE_NAME => 'que',
142
      P_ID         => 'que_id',
143
      P_OWNER_INFO => array(
144
        array(
145
          P_LOCATION    => LOC_USER,
146
          P_OWNER_FIELD => 'que_player_id',
147
        ),
148
149
        array(
150
          P_LOCATION    => LOC_PLANET,
151
          P_OWNER_FIELD => 'que_planet_id_origin',
152
        ),
153
154
        array(
155
          P_LOCATION    => LOC_PLANET,
156
          P_OWNER_FIELD => 'que_planet_id',
157
        ),
158
      ),
159
    ),
160
161
    LOC_FLEET => array(
162
      P_TABLE_NAME => 'fleets',
163
      P_ID         => 'fleet_id',
164
      P_OWNER_INFO => array(
165
        array(
166
          P_LOCATION    => LOC_USER,
167
          P_OWNER_FIELD => 'fleet_owner',
168
        ),
169
170
        array(
171
          P_LOCATION    => LOC_USER,
172
          P_OWNER_FIELD => 'fleet_target_owner',
173
        ),
174
175
        array(
176
          P_LOCATION    => LOC_PLANET,
177
          P_OWNER_FIELD => 'fleet_start_planet_id',
178
        ),
179
180
        array(
181
          P_LOCATION    => LOC_PLANET,
182
          P_OWNER_FIELD => 'fleet_end_planet_id',
183
        ),
184
      ),
185
    ),
186
  );
187
188
//  /**
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
189
//   * @param $db db_mysql
190
//   */
191
//  public static function init_main_db($db) {
192
//    self::$db = $db;
193
//    self::$db->sn_db_connect();
194
//  }
195
196
197
  public static function log_file($message, $spaces = 0) {
198
    if (self::$debug) {
199
      self::$debug->log_file($message, $spaces);
200
    }
201
  }
202
203
  public static function debug_set_handler($debug) {
204
    self::$debug = $debug;
205
  }
206
207
208
  // TODO Вынести в отдельный объект
209
  /**
210
   * Эта функция проверяет статус транзакции
211
   *
212
   * Это - низкоуровневая функция. В нормальном состоянии движка её сообщения никогда не будут видны
213
   *
214
   * @param null|true|false $status Должна ли быть запущена транзакция в момент проверки
215
   *   <p>null - транзакция НЕ должна быть запущена</p>
216
   *   <p>true - транзакция должна быть запущена - для совместимости с $for_update</p>
217
   *   <p>false - всё равно - для совместимости с $for_update</p>
218
   *
219
   * @return bool Текущий статус транзакции
220
   */
221
  public static function db_transaction_check($status = null) {
222
    $error_msg = false;
223
    if ($status && !static::$db_in_transaction) {
224
      $error_msg = 'No transaction started for current operation';
225
    } elseif ($status === null && static::$db_in_transaction) {
226
      $error_msg = 'Transaction is already started';
227
    }
228
229
    if (!empty($error_msg)) {
230
      // TODO - Убрать позже
231
      print('<h1>СООБЩИТЕ ЭТО АДМИНУ: sn_db_transaction_check() - ' . $error_msg . '</h1>');
232
      $backtrace = debug_backtrace();
233
      array_shift($backtrace);
234
      pdump($backtrace);
235
      die($error_msg);
236
    }
237
238
    return static::$db_in_transaction;
239
  }
240
241
  public static function db_transaction_start($level = '') {
242
    static::db_transaction_check(null);
243
244
    $level ? doquery('SET TRANSACTION ISOLATION LEVEL ' . $level) : false;
245
246
    static::$transaction_id++;
247
    doquery('START TRANSACTION');
248
249
    if (classSupernova::$config->db_manual_lock_enabled) {
250
      classSupernova::$config->db_loadItem('var_db_manually_locked');
251
      classSupernova::$config->db_saveItem('var_db_manually_locked', SN_TIME_SQL);
252
    }
253
254
    static::$db_in_transaction = true;
255
    SnCache::locatorReset();
256
    SnCache::queriesReset();
257
258
    return static::$transaction_id;
259
  }
260
261
  public static function db_transaction_commit() {
262
    static::db_transaction_check(true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a null|object<true>|false.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
263
264
    if (!empty(static::$delayed_changset)) {
265
      static::db_changeset_apply(static::$delayed_changset, true);
266
    }
267
    doquery('COMMIT');
268
269
    return static::db_transaction_clear();
270
  }
271
272
  public static function db_transaction_rollback() {
273
    // static::db_transaction_check(true); // TODO - вообще-то тут тоже надо проверять есть ли транзакция
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...
274
275
    if (!empty(static::$delayed_changset)) {
276
//      static::db_changeset_revert();
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...
277
      // TODO Для этапа 1 - достаточно чистить только те таблицы, что были затронуты
278
      // Для этапа 2 - чистить только записи
279
      // Для этапа 3 - возвращать всё
280
      SnCache::cache_clear_all(true);
281
    }
282
    doquery('ROLLBACK');
283
284
    return static::db_transaction_clear();
285
  }
286
287
  protected static function db_transaction_clear() {
288
    static::$delayed_changset = array();
289
    SnCache::cache_lock_unset_all();
290
291
    static::$db_in_transaction = false;
292
    static::$db_records_locked = false;
293
    static::$transaction_id++;
294
295
    return static::$transaction_id;
296
  }
297
298
  /**
299
   * Блокирует указанные таблицу/список таблиц
300
   *
301
   * @param string|array $tables Таблица/список таблиц для блокировки. Названия таблиц - без префиксов
302
   * <p>string - название таблицы для блокировки</p>
303
   * <p>array - массив, где ключ - имя таблицы, а значение - условия блокировки элементов</p>
304
   */
305
  public static function db_lock_tables($tables) {
306
    $tables = is_array($tables) ? $tables : array($tables => '');
307
    foreach ($tables as $table_name => $condition) {
308
      self::$db->doquery("SELECT 1 FROM {{{$table_name}}}" . ($condition ? ' WHERE ' . $condition : ''));
309
    }
310
  }
311
312
  /**
313
   * @param      $query
314
   * @param bool $fetch
315
   * @param bool $skip_lock
316
   *
317
   * @return array|bool|mysqli_result|null
318
   */
319
  public static function db_query($query, $fetch = false, $skip_lock = false) {
320
    $select = strpos(strtoupper($query), 'SELECT') !== false;
321
322
    $query .= $select && $fetch ? ' LIMIT 1' : '';
323
    $query .= $select && !$skip_lock && static::db_transaction_check(false) ? ' FOR UPDATE' : '';
324
325
    $result = self::$db->doquery($query, $fetch);
0 ignored issues
show
Documentation introduced by
$fetch is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
326
327
    return $result;
328
  }
329
330
  /**
331
   * Возвращает информацию о записи по её ID
332
   *
333
   * @param int       $location_type
334
   * @param int|array $record_id_unsafe
335
   *    <p>int - ID записи</p>
336
   *    <p>array - запись пользователя с установленным полем P_ID</p>
337
   * @param bool      $for_update @deprecated
338
   * @param string    $fields @deprecated список полей или '*'/'' для всех полей
339
   * @param bool      $skip_lock Указывает на то, что не нужно блокировать запись //TODO и не нужно сохранять в кэше
340
   *
341
   * @return array|false
342
   *    <p>false - Нет записи с указанным ID</p>
343
   *    <p>array - запись</p>
344
   */
345
  public static function db_get_record_by_id($location_type, $record_id_unsafe, $for_update = false, $fields = '*', $skip_lock = false) {
0 ignored issues
show
Unused Code introduced by
The parameter $for_update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $fields is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $skip_lock is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
346
    $id_field = static::$location_info[$location_type][P_ID];
347
    $record_id_safe = idval(is_array($record_id_unsafe) && isset($record_id_unsafe[$id_field]) ? $record_id_unsafe[$id_field] : $record_id_unsafe);
348
349
    return static::db_get_record_list($location_type, "`{$id_field}` = {$record_id_safe}", true, false);
350
  }
351
352
  public static function db_get_record_list($location_type, $filter = '', $fetch = false, $no_return = false) {
353
    if (SnCache::isQueryCacheByLocationAndFilterEmpty($location_type, $filter)) {
354
      SnCache::queryCacheResetByLocationAndFilter($location_type, $filter);
355
356
      $location_info = &static::$location_info[$location_type];
357
      $id_field = $location_info[P_ID];
358
359
      if (static::db_transaction_check(false)) {
360
        // Проходим по всем родителям данной записи
361
        foreach ($location_info[P_OWNER_INFO] as $owner_data) {
362
          $owner_location_type = $owner_data[P_LOCATION];
363
          $parent_id_list = array();
364
          // Выбираем родителей данного типа и соответствующие ИД текущего типа
365
          $query = static::db_query(
366
            "SELECT
367
              distinct({{{$location_info[P_TABLE_NAME]}}}.{$owner_data[P_OWNER_FIELD]}) AS parent_id
368
            FROM {{{$location_info[P_TABLE_NAME]}}}" .
369
            ($filter ? ' WHERE ' . $filter : '') .
370
            ($fetch ? ' LIMIT 1' : ''), false, true);
371
372
          while ($row = db_fetch($query)) {
373
            // Исключаем из списка родительских ИД уже заблокированные записи
374
            if (!SnCache::cache_lock_get($owner_location_type, $row['parent_id'])) {
375
              $parent_id_list[$row['parent_id']] = $row['parent_id'];
376
            }
377
          }
378
          // Если все-таки какие-то записи еще не заблокированы - вынимаем текущие версии из базы
379
          if ($indexes_str = implode(',', $parent_id_list)) {
380
            $parent_id_field = static::$location_info[$owner_location_type][P_ID];
381
            static::db_get_record_list($owner_location_type,
382
              $parent_id_field . (count($parent_id_list) > 1 ? " IN ({$indexes_str})" : " = {$indexes_str}"), $fetch, true);
383
          }
384
        }
385
      }
386
387
      $query = static::db_query(
388
        "SELECT * FROM {{{$location_info[P_TABLE_NAME]}}}" .
389
        (($filter = trim($filter)) ? " WHERE {$filter}" : '')
390
      );
391
      while ($row = db_fetch($query)) {
392
        // Caching record in row cache
393
        SnCache::cache_set($location_type, $row);
394
        // Making ref to cached record in query cache
395
        SnCache::queryCacheSetByFilter($location_type, $filter, $row[$id_field]);
396
      }
397
    }
398
399
    if ($no_return) {
400
      return true;
401
    } else {
402
      $result = false;
403
//      $queryCache = SnCache::getQueriesByLocationAndFilter($location_type, $filter);
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
404
//      if (is_array($queryCache)) {
405
//        foreach ($queryCache as $key => $value) {
406
      foreach (SnCache::getQueriesByLocationAndFilter($location_type, $filter) as $key => $value) {
407
        $result[$key] = $value;
408
        if ($fetch) {
409
          break;
410
        }
411
      }
412
413
//      }
414
415
      return $fetch ? (is_array($result) ? reset($result) : false) : $result;
416
    }
417
  }
418
419
  /**
420
   * @param int    $location_type
421
   * @param int    $record_id
422
   * @param string $set - SQL SET structure
423
   *
424
   * @return array|bool|mysqli_result|null
425
   */
426
  public static function db_upd_record_by_id($location_type, $record_id, $set) {
427
    if (!($record_id = idval($record_id)) || !($set = trim($set))) {
428
      return false;
429
    }
430
431
    $id_field = static::$location_info[$location_type][P_ID];
432
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
433
    if ($result = static::db_query($q = "UPDATE {{{$table_name}}} SET {$set} WHERE `{$id_field}` = {$record_id}")) // TODO Как-то вернуть может быть LIMIT 1 ?
434
    {
435
      if (static::$db->db_affected_rows()) {
436
        // Обновляем данные только если ряд был затронут
437
        // TODO - переделать под работу со структурированными $set
438
439
        // Тут именно так, а не cache_unset - что бы в кэшах автоматически обновилась запись. Будет нужно на будущее
440
        //static::$data[$location_type][$record_id] = null;
0 ignored issues
show
Unused Code Comprehensibility introduced by
79% 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...
441
        SnCache::cacheUnsetElement($location_type, $record_id);
442
        // Вытаскиваем обновленную запись
443
        static::db_get_record_by_id($location_type, $record_id);
444
        SnCache::cache_clear($location_type, false); // Мягкий сброс - только $queries
445
      }
446
    }
447
448
    return $result;
449
  }
450
451
  public static function db_upd_record_list($location_type, $condition, $set) {
452
    if (!($set = trim($set))) {
453
      return false;
454
    }
455
456
    $condition = trim($condition);
457
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
458
459
    if ($result = static::db_query("UPDATE {{{$table_name}}} SET " . $set . ($condition ? ' WHERE ' . $condition : ''))) {
460
461
      if (static::$db->db_affected_rows()) { // Обновляем данные только если ряд был затронут
462
        // Поскольку нам неизвестно, что и как обновилось - сбрасываем кэш этого типа полностью
463
        // TODO - когда будет структурированный $condition и $set - перепаковывать данные
464
        SnCache::cache_clear($location_type, true);
465
      }
466
    }
467
468
    return $result;
469
  }
470
471
  /**
472
   * @param int    $location_type
473
   * @param string $set
474
   *
475
   * @return array|bool|false|mysqli_result|null
476
   */
477
  public static function db_ins_record($location_type, $set) {
478
    $set = trim($set);
479
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
480 View Code Duplication
    if ($result = static::db_query("INSERT INTO `{{{$table_name}}}` SET {$set}")) {
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...
481
      if (static::$db->db_affected_rows()) // Обновляем данные только если ряд был затронут
482
      {
483
        $record_id = classSupernova::$db->db_insert_id();
484
        // Вытаскиваем запись целиком, потому что в $set могли быть "данные по умолчанию"
485
        $result = static::db_get_record_by_id($location_type, $record_id);
486
        // Очищаем второстепенные кэши - потому что вставленная запись могла повлиять на результаты запросов или локация или еще чего
487
        // TODO - когда будет поддержка изменения индексов и локаций - можно будет вызывать её
488
        SnCache::cache_clear($location_type, false); // Мягкий сброс - только $queries
489
      }
490
    }
491
492
    return $result;
493
  }
494
495
  public static function db_ins_field_set($location_type, $field_set, $serialize = false) {
496
    // TODO multiinsert
497
    !sn_db_field_set_is_safe($field_set) ? $field_set = sn_db_field_set_make_safe($field_set, $serialize) : false;
498
    sn_db_field_set_safe_flag_clear($field_set);
499
    $values = implode(',', $field_set);
500
    $fields = implode(',', array_keys($field_set));
501
502
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
503 View Code Duplication
    if ($result = static::db_query("INSERT INTO `{{{$table_name}}}` ({$fields}) VALUES ({$values});")) {
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...
504
      if (static::$db->db_affected_rows()) {
505
        // Обновляем данные только если ряд был затронут
506
        $record_id = classSupernova::$db->db_insert_id();
507
        // Вытаскиваем запись целиком, потому что в $set могли быть "данные по умолчанию"
508
        $result = static::db_get_record_by_id($location_type, $record_id);
509
        // Очищаем второстепенные кэши - потому что вставленная запись могла повлиять на результаты запросов или локация или еще чего
510
        // TODO - когда будет поддержка изменения индексов и локаций - можно будет вызывать её
511
        SnCache::cache_clear($location_type, false); // Мягкий сброс - только $queries
512
      }
513
    }
514
515
    return $result;
516
  }
517
518
  public static function db_del_record_by_id($location_type, $safe_record_id) {
519
    if (!($safe_record_id = idval($safe_record_id))) {
520
      return false;
521
    }
522
523
    $id_field = static::$location_info[$location_type][P_ID];
524
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
525
    if ($result = static::db_query("DELETE FROM `{{{$table_name}}}` WHERE `{$id_field}` = {$safe_record_id}")) {
526
      // Обновляем данные только если ряд был затронут
527
      if (static::$db->db_affected_rows()) {
528
        SnCache::cache_unset($location_type, $safe_record_id);
529
      }
530
    }
531
532
    return $result;
533
  }
534
535
  public static function db_del_record_list($location_type, $condition) {
536
    if (!($condition = trim($condition))) {
537
      return false;
538
    }
539
540
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
541
542
    if ($result = static::db_query("DELETE FROM `{{{$table_name}}}` WHERE {$condition}")) {
543
      // Обновляем данные только если ряд был затронут
544
      if (static::$db->db_affected_rows()) {
545
        // Обнуление кэша, потому что непонятно, что поменялось
546
        // TODO - когда будет структурированный $condition можно будет делать только cache_unset по нужным записям
547
        SnCache::cache_clear($location_type);
548
      }
549
    }
550
551
    return $result;
552
  }
553
554
555
556
  // Работа с пользователями
557
  /**
558
   * Возвращает информацию о пользователе по его ID
559
   *
560
   * @param int|array $user_id_unsafe
561
   *    <p>int - ID пользователя</p>
562
   *    <p>array - запись пользователя с установленным полем ['id']</p>
563
   * @param bool      $for_update @deprecated
564
   * @param string    $fields @deprecated список полей или '*'/'' для всех полей
565
   * @param null      $player
566
   * @param bool|null $player Признак выбора записи пользователь типа "игрок"
567
   *    <p>null - Можно выбрать запись любого типа</p>
568
   *    <p>true - Выбирается только запись типа "игрок"</p>
569
   *    <p>false - Выбирается только запись типа "альянс"</p>
570
   *
571
   * @return array|false
572
   *    <p>false - Нет записи с указанным ID и $player</p>
573
   *    <p>array - запись типа $user</p>
574
   */
575
  public static function db_get_user_by_id($user_id_unsafe, $for_update = false, $fields = '*', $player = null) {
576
    $user = static::db_get_record_by_id(LOC_USER, $user_id_unsafe, $for_update, $fields);
577
578
    return (is_array($user) &&
579
      (
580
        $player === null
581
        ||
582
        ($player === true && !$user['user_as_ally'])
583
        ||
584
        ($player === false && $user['user_as_ally'])
585
      )) ? $user : false;
586
  }
587
588
  public static function db_get_user_by_username($username_unsafe, $for_update = false, $fields = '*', $player = null, $like = false) {
0 ignored issues
show
Unused Code introduced by
The parameter $for_update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $fields is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
589
    // TODO Проверить, кстати - а везде ли нужно выбирать юзеров или где-то все-таки ищутся Альянсы ?
590
    if (!($username_unsafe = trim($username_unsafe))) {
591
      return false;
592
    }
593
594
    $user = null;
595
    if (SnCache::isArrayLocation(LOC_USER)) {
596
      foreach (SnCache::getData(LOC_USER) as $user_id => $user_data) {
597
        if (is_array($user_data) && isset($user_data['username'])) {
598
          // проверяем поле
599
          // TODO Возможно есть смысл всегда искать по strtolower - но может игрок захочет переименоваться с другим регистром? Проверить!
600
          if ((!$like && $user_data['username'] == $username_unsafe) || ($like && strtolower($user_data['username']) == strtolower($username_unsafe))) {
601
            // $user_as_ally = intval($user_data['user_as_ally']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% 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...
602
            $user_as_ally = idval($user_data['user_as_ally']);
603
            if ($player === null || ($player === true && !$user_as_ally) || ($player === false && $user_as_ally)) {
604
              $user = $user_data;
605
              break;
606
            }
607
          }
608
        }
609
      }
610
    }
611
612
    if ($user === null) {
613
      // Вытаскиваем запись
614
      $username_safe = db_escape($like ? strtolower($username_unsafe) : $username_unsafe); // тут на самом деле strtolower() лишняя, но пусть будет
615
616
      $user = static::db_query(
617
        "SELECT * FROM {{users}} WHERE `username` " . ($like ? 'LIKE' : '=') . " '{$username_safe}'"
618
        , true);
619
      SnCache::cache_set(LOC_USER, $user); // В кэш-юзер так же заполнять индексы
620
    }
621
622
    return $user;
623
  }
624
625
626
  public static function db_get_user_by_where($where_safe, $for_update = false, $fields = '*') {
0 ignored issues
show
Unused Code introduced by
The parameter $for_update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $fields is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
627
    $user = null;
628
    // TODO переделать на индексы
629
630
    if ($user === null && !empty($where_safe)) {
631
      // Вытаскиваем запись
632
      $user = static::db_query("SELECT * FROM {{users}} WHERE {$where_safe}", true);
633
634
      SnCache::cache_set(LOC_USER, $user); // В кэш-юзер так же заполнять индексы
635
    }
636
637
    return $user;
638
  }
639
640
641 View Code Duplication
  public static function db_unit_time_restrictions($date = SN_TIME_NOW) {
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...
642
    $date = is_numeric($date) ? "FROM_UNIXTIME({$date})" : "'{$date}'";
643
644
    return
645
      "(unit_time_start IS NULL OR unit_time_start <= {$date}) AND
646
    (unit_time_finish IS NULL OR unit_time_finish = '1970-01-01 03:00:00' OR unit_time_finish >= {$date})";
647
  }
648
649
  public static function db_get_unit_by_id($unit_id, $for_update = false, $fields = '*') {
650
    // TODO запихивать в $data[LOC_LOCATION][$location_type][$location_id]
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% 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...
651
    $unit = static::db_get_record_by_id(LOC_UNIT, $unit_id, $for_update, $fields);
652
//    if (is_array($unit)) {
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...
653
//      // static::$locator[LOC_UNIT][$unit['unit_location_type']][$unit['unit_location_id']][$unit['unit_snid']] = &SnCache::$data[LOC_UNIT][$unit_id];
654
//      SnCache::$locator[LOC_UNIT][$unit['unit_location_type']][$unit['unit_location_id']][$unit['unit_snid']] = &SnCache::getDataRefByLocationAndId(LOC_UNIT, $unit_id);
655
//    }
656
    SnCache::setUnitLocator($unit, $unit_id);
657
658
    return $unit;
659
  }
660
661
  /**
662
   * @param int $user_id
663
   * @param int $location_type
664
   * @param int $location_id
665
   *
666
   * @return array|bool
667
   */
668
  public static function db_get_unit_list_by_location($user_id = 0, $location_type, $location_id) {
0 ignored issues
show
Unused Code introduced by
The parameter $user_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
669
    if (!($location_type = idval($location_type)) || !($location_id = idval($location_id))) {
670
      return false;
671
    }
672
673
    if (SnCache::isUnitLocatorNotSet($location_type, $location_id)) {
674
      $got_data = static::db_get_record_list(LOC_UNIT, "unit_location_type = {$location_type} AND unit_location_id = {$location_id} AND " . static::db_unit_time_restrictions());
675
      if (!empty($got_data) && is_array($got_data)) {
676
        foreach ($got_data as $unit_id => $unit_data) {
677
          SnCache::setUnitLocatorByLocationAndIDs($location_type, $location_id, $unit_data);
678
        }
679
      }
680
    }
681
682
    $result = false;
683
    foreach (SnCache::getUnitLocatorByFullLocation($location_type, $location_id) as $key => $value) {
684
      $result[$key] = $value;
685
    }
686
687
    return $result;
688
  }
689
690
  public static function db_get_unit_by_location($user_id = 0, $location_type, $location_id, $unit_snid = 0, $for_update = false, $fields = '*') {
0 ignored issues
show
Unused Code introduced by
The parameter $for_update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $fields is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
691
    static::db_get_unit_list_by_location($user_id, $location_type, $location_id);
692
693
    return SnCache::getUnitLocator($location_type, $location_id, $unit_snid);
694
  }
695
696
697
  /*
698
   * С $for_update === true эта функция должна вызываться только из транзакции! Все соответствующие записи в users и planets должны быть уже блокированы!
699
   *
700
   * $que_type
701
   *   !$que_type - все очереди
702
   *   QUE_XXXXXX - конкретная очередь по планете
703
   * $user_id - ID пользователя
704
   * $planet_id
705
   *   $que_type == QUE_RESEARCH - игнорируется
706
   *   null - обработка очередей планет не производится
707
   *   false/0 - обрабатываются очереди всех планет по $user_id
708
   *   (integer) - обрабатываются локальные очереди для планеты. Нужно, например, в обработчике флотов
709
   *   иначе - $que_type для указанной планеты
710
   * $for_update - true == нужно блокировать записи
711
   *
712
   * TODO Работа при !$user_id
713
   * TODO Переформатировать вывод данных, что бы можно было возвращать данные по всем планетам и юзерам в одном запросе: добавить подмассивы 'que', 'planets', 'players'
714
   *
715
   */
716
  public static function db_que_list_by_type_location($user_id, $planet_id = null, $que_type = false, $for_update = false) {
0 ignored issues
show
Unused Code introduced by
The parameter $for_update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
717
    if (!$user_id) {
718
      pdump(debug_backtrace());
719
      die('No user_id for que_get_que()');
720
    }
721
722
    $ques = array();
723
724
    $query = array();
725
726
    if ($user_id = idval($user_id)) {
727
      $query[] = "`que_player_id` = {$user_id}";
728
    }
729
730
    if ($que_type == QUE_RESEARCH || $planet_id === null) {
731
      $query[] = "`que_planet_id` IS NULL";
732
    } elseif ($planet_id) {
733
      $query[] = "(`que_planet_id` = {$planet_id}" . ($que_type ? '' : ' OR que_planet_id IS NULL') . ")";
734
    }
735
    if ($que_type) {
736
      $query[] = "`que_type` = {$que_type}";
737
    }
738
739
    $ques['items'] = static::db_get_record_list(LOC_QUE, implode(' AND ', $query));
740
741
    return que_recalculate($ques);
742
  }
743
744
745 View Code Duplication
  public static function db_changeset_prepare_unit($unit_id, $unit_value, $user, $planet_id = null) {
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...
746
    if (!is_array($user)) {
747
      // TODO - remove later
748
      print('<h1>СООБЩИТЕ ЭТО АДМИНУ: sn_db_unit_changeset_prepare() - USER is not ARRAY</h1>');
749
      pdump(debug_backtrace());
750
      die('USER is not ARRAY');
751
    }
752
    if (!isset($user['id']) || !$user['id']) {
753
      // TODO - remove later
754
      print('<h1>СООБЩИТЕ ЭТО АДМИНУ: sn_db_unit_changeset_prepare() - USER[id] пустой</h1>');
755
      pdump($user);
756
      pdump(debug_backtrace());
757
      die('USER[id] пустой');
758
    }
759
    $planet_id = is_array($planet_id) && isset($planet_id['id']) ? $planet_id['id'] : $planet_id;
760
761
    $unit_location = sys_get_unit_location($user, array(), $unit_id);
762
    $location_id = $unit_location == LOC_USER ? $user['id'] : $planet_id;
763
    $location_id = $location_id ? $location_id : 'NULL';
764
765
    $temp = DBStaticUnit::db_unit_by_location($user['id'], $unit_location, $location_id, $unit_id, true, 'unit_id');
766
    if ($temp['unit_id']) {
767
      $db_changeset = array(
768
        'action'  => SQL_OP_UPDATE,
769
        P_VERSION => 1,
770
        'where'   => array(
771
          "unit_id" => $temp['unit_id'],
772
        ),
773
        'fields'  => array(
774
          'unit_level' => array(
775
            'delta' => $unit_value
776
          ),
777
        ),
778
      );
779
    } else {
780
      $db_changeset = array(
781
        'action' => SQL_OP_INSERT,
782
        'fields' => array(
783
          'unit_player_id'     => array(
784
            'set' => $user['id'],
785
          ),
786
          'unit_location_type' => array(
787
            'set' => $unit_location,
788
          ),
789
          'unit_location_id'   => array(
790
            'set' => $unit_location == LOC_USER ? $user['id'] : $planet_id,
791
          ),
792
          'unit_type'          => array(
793
            'set' => get_unit_param($unit_id, P_UNIT_TYPE),
794
          ),
795
          'unit_snid'          => array(
796
            'set' => $unit_id,
797
          ),
798
          'unit_level'         => array(
799
            'set' => $unit_value,
800
          ),
801
        ),
802
      );
803
    }
804
805
    return $db_changeset;
806
  }
807
808
809
  public function db_changeset_delay($table_name, $table_data) {
810
    // TODO Применять ченджсет к записям
811
    static::$delayed_changset[$table_name] = is_array(static::$delayed_changset[$table_name]) ? static::$delayed_changset[$table_name] : array();
812
    // TODO - На самом деле дурацкая оптимизация, если честно - может быть идентичные записи с идентичными дельтами - и привет. Но не должны, конечно
813
    static::$delayed_changset[$table_name] = array_merge(static::$delayed_changset[$table_name], $table_data);
814
  }
815
816
  public function db_changeset_condition_compile(&$conditions, &$table_name = '') {
817
    if (!$conditions[P_LOCATION] || $conditions[P_LOCATION] == LOC_NONE) {
818
      $conditions[P_LOCATION] = LOC_NONE;
819
      switch ($table_name) {
820
        case 'users':
821
        case LOC_USER:
822
          $conditions[P_TABLE_NAME] = $table_name = 'users';
823
          $conditions[P_LOCATION] = LOC_USER;
824
        break;
825
826
        case 'planets':
827
        case LOC_PLANET:
828
          $conditions[P_TABLE_NAME] = $table_name = 'planets';
829
          $conditions[P_LOCATION] = LOC_PLANET;
830
        break;
831
832
        case 'unit':
833
        case LOC_UNIT:
834
          $conditions[P_TABLE_NAME] = $table_name = 'unit';
835
          $conditions[P_LOCATION] = LOC_UNIT;
836
        break;
837
      }
838
    }
839
840
    $conditions[P_FIELDS_STR] = '';
841
    if ($conditions['fields']) {
842
      $fields = array();
843 View Code Duplication
      foreach ($conditions['fields'] as $field_name => $field_data) {
0 ignored issues
show
Bug introduced by
The expression $conditions['fields'] of type string is not traversable.
Loading history...
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...
844
        $condition = "`{$field_name}` = ";
845
        $value = '';
846
        if ($field_data['delta']) {
847
          $value = "`{$field_name}`" . ($field_data['delta'] >= 0 ? '+' : '') . $field_data['delta'];
848
        } elseif ($field_data['set']) {
849
          $value = (is_string($field_data['set']) ? "'{$field_data['set']}'" : $field_data['set']);
850
        }
851
852
        if ($value) {
853
          $fields[] = $condition . $value;
854
        }
855
      }
856
      $conditions[P_FIELDS_STR] = implode(',', $fields);
857
    }
858
859
    $conditions[P_WHERE_STR] = '';
860
    if (!empty($conditions['where'])) {
861
      if ($conditions[P_VERSION] == 1) {
862
        $the_conditions = array();
863
        foreach ($conditions['where'] as $field_id => $field_value) {
0 ignored issues
show
Bug introduced by
The expression $conditions['where'] of type string is not traversable.
Loading history...
864
          // Простое условие - $field_id = $field_value
865
          if (is_string($field_id)) {
866
            $field_value =
867
              $field_value === null ? 'NULL' :
868
                (is_string($field_value) ? "'" . db_escape($field_value) . "'" :
869
                  (is_bool($field_value) ? intval($field_value) : $field_value));
870
            $the_conditions[] = "`{$field_id}` = {$field_value}";
871
          } else {
872
            die('Неподдерживаемый тип условия');
873
          }
874
        }
875
      } else {
876
        $the_conditions = &$conditions['where'];
877
      }
878
      $conditions[P_WHERE_STR] = implode(' AND ', $the_conditions);
879
    }
880
881
    switch ($conditions['action']) {
882
      case SQL_OP_DELETE:
883
        $conditions[P_ACTION_STR] = ("DELETE FROM {{{$table_name}}}");
884
      break;
885
      case SQL_OP_UPDATE:
886
        $conditions[P_ACTION_STR] = ("UPDATE {{{$table_name}}} SET");
887
      break;
888
      case SQL_OP_INSERT:
889
        $conditions[P_ACTION_STR] = ("INSERT INTO {{{$table_name}}} SET");
890
      break;
891
      // case SQL_OP_REPLACE: $result = doquery("REPLACE INTO {{{$table_name}}} SET {$fields}") && $result; break;
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...
892
      default:
893
        die('Неподдерживаемая операция в classSupernova::db_changeset_condition_compile');
894
    }
895
896
    $conditions[P_QUERY_STR] = $conditions[P_ACTION_STR] . ' ' . $conditions[P_FIELDS_STR] . (' WHERE ' . $conditions[P_WHERE_STR]);
897
  }
898
899
  public static function db_changeset_apply($db_changeset, $flush_delayed = false) {
0 ignored issues
show
Unused Code introduced by
The parameter $flush_delayed is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
900
    $result = true;
901
    if (!is_array($db_changeset) || empty($db_changeset)) {
902
      return $result;
903
    }
904
905
    foreach ($db_changeset as $table_name => &$table_data) {
906
      // TODO - delayed changeset
907
      foreach ($table_data as $record_id => &$conditions) {
908
        static::db_changeset_condition_compile($conditions, $table_name);
909
910
        if ($conditions['action'] != SQL_OP_DELETE && !$conditions[P_FIELDS_STR]) {
911
          continue;
912
        }
913
        if ($conditions['action'] == SQL_OP_DELETE && !$conditions[P_WHERE_STR]) {
914
          continue;
915
        } // Защита от случайного удаления всех данных в таблице
916
917
        if ($conditions[P_LOCATION] != LOC_NONE) {
918
          switch ($conditions['action']) {
919
            case SQL_OP_DELETE:
920
              $result = self::db_del_record_list($conditions[P_LOCATION], $conditions[P_WHERE_STR]) && $result;
921
            break;
922
            case SQL_OP_UPDATE:
923
              $result = self::db_upd_record_list($conditions[P_LOCATION], $conditions[P_WHERE_STR], $conditions[P_FIELDS_STR]) && $result;
924
            break;
925
            case SQL_OP_INSERT:
926
              $result = self::db_ins_record($conditions[P_LOCATION], $conditions[P_FIELDS_STR]) && $result;
927
            break;
928
            default:
929
              die('Неподдерживаемая операция в classSupernova::db_changeset_apply');
930
            // case SQL_OP_REPLACE: $result = $result && doquery("REPLACE INTO {{{$table_name}}} SET {$fields}"); break;
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...
931
          }
932
        } else {
933
          $result = doquery($conditions[P_QUERY_STR]) && $result;
934
        }
935
      }
936
    }
937
938
    return $result;
939
  }
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
  // que_process не всегда должна работать в режиме прямой работы с БД !! Она может работать и в режиме эмуляции
976
  // !!!!!!!! После que_get брать не [0] элемент, а first() - тогда можно в индекс элемента засовывать que_id из таблицы
977
978
979
  public static function init_0_prepare() {
980
    // Отключаем magic_quotes
981
    ini_get('magic_quotes_sybase') ? die('SN is incompatible with \'magic_quotes_sybase\' turned on. Disable it in php.ini or .htaccess...') : false;
982
    if (@get_magic_quotes_gpc()) {
983
      $gpcr = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
984
      array_walk_recursive($gpcr, function (&$value, $key) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
985
        $value = stripslashes($value);
986
      });
987
    }
988
    if (function_exists('set_magic_quotes_runtime')) {
989
      @set_magic_quotes_runtime(0);
990
      @ini_set('magic_quotes_runtime', 0);
991
      @ini_set('magic_quotes_sybase', 0);
992
    }
993
  }
994
995
  public static function init_1_globalContainer() {
996
997
    $container = new Pimple\GlobalContainer(array(
998
      'buddyClass' => 'Buddy\BuddyModel',
999
    ));
1000
1001
    $container->db = function ($c) {};
0 ignored issues
show
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1002
1003
      $container->db = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1004
      $db = new db_mysql();
1005
      $db->sn_db_connect();
1006
1007
      return $db;
1008
    };
1009
1010
    $container->debug = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1011
      return new debug();
1012
    };
1013
1014
    $container->cache = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1015
      return new classCache(classSupernova::$cache_prefix);
1016
    };
1017
1018
    $container->config = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1019
      return new classConfig(classSupernova::$cache_prefix);
1020
    };
1021
1022
    $container->dbRowOperator = function ($c) {
1023
      return new DbRowSimple($c);
0 ignored issues
show
Unused Code introduced by
The call to DbRowSimple::__construct() has too many arguments starting with $c.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1024
    };
1025
1026
    $container->buddy = $container->factory(function ($c) {
1027
      return new $c->buddyClass($c);
1028
    });
1029
//    $container->buddy = $container->factory(function ($c) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
1030
//      return new Buddy\Buddy($c);
1031
//    });
1032
1033
    $container->query = $container->factory(function (Pimple\GlobalContainer $c) {
1034
      return new DbQueryConstructor($c->db);
0 ignored issues
show
Bug introduced by
It seems like $c->db can also be of type object<Closure>; however, DbSqlAware::__construct() does only seem to accept object<db_mysql>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1035
    });
1036
1037
// TODO
0 ignored issues
show
Unused Code Comprehensibility introduced by
49% 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...
1038
//    $container->vector = $container->factory(function (Pimple\GlobalContainer $c) {
1039
//      return new DbQueryConstructor($c->db);
1040
//    });
1041
1042
    static::$gc = $container;
1043
  }
1044
1045
  public static function init_3_load_config_file() {
1046
    $dbsettings = array();
1047
1048
    require(SN_ROOT_PHYSICAL . "config" . DOT_PHP_EX);
1049
    self::$cache_prefix = !empty($dbsettings['cache_prefix']) ? $dbsettings['cache_prefix'] : $dbsettings['prefix'];
1050
    self::$db_name = $dbsettings['name'];
1051
    self::$sn_secret_word = $dbsettings['secretword'];
1052
    unset($dbsettings);
1053
  }
1054
1055
  public static function init_global_objects() {
1056
    self::$debug = self::$gc->debug;
0 ignored issues
show
Documentation Bug introduced by
It seems like self::$gc->debug can also be of type object<Closure>. However, the property $debug is declared as type object<debug>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1057
    self::$db = self::$gc->db;
0 ignored issues
show
Documentation Bug introduced by
It seems like self::$gc->db can also be of type object<Closure>. However, the property $db is declared as type object<db_mysql>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1058
//    classSupernova::init_main_db(new db_mysql());
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
1059
    self::$user_options = new userOptions(0);
1060
1061
    // Initializing global 'cacher' object
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% 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...
1062
//    static::$cache = new classCache(classSupernova::$cache_prefix);
1063
    self::$cache = self::$gc->cache;
0 ignored issues
show
Documentation Bug introduced by
It seems like self::$gc->cache can also be of type object<Closure>. However, the property $cache is declared as type object<classCache>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1064
1065
    empty(static::$cache->tables) ? sys_refresh_tablelist() : false;
1066
    empty(static::$cache->tables) ? die('DB error - cannot find any table. Halting...') : false;
1067
1068
    // Initializing global "config" object
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% 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...
1069
//    static::$config = new classConfig(classSupernova::$cache_prefix);
1070
    static::$config = self::$gc->config;
0 ignored issues
show
Documentation Bug introduced by
It seems like self::$gc->config can also be of type object<Closure>. However, the property $config is declared as type object<classConfig>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1071
1072
    // Initializing statics
1073
    Vector::_staticInit(static::$config);
0 ignored issues
show
Bug introduced by
It seems like static::$config can also be of type object<Closure>; however, Vector\Vector::_staticInit() does only seem to accept object<classConfig>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1074
  }
1075
1076
  public static function init_debug_state() {
1077
    if ($_SERVER['SERVER_NAME'] == 'localhost' && !defined('BE_DEBUG')) {
1078
      define('BE_DEBUG', true);
1079
    }
1080
    // define('DEBUG_SQL_ONLINE', true); // Полный дамп запросов в рил-тайме. Подойдет любое значение
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...
1081
    define('DEBUG_SQL_ERROR', true); // Выводить в сообщении об ошибке так же полный дамп запросов за сессию. Подойдет любое значение
1082
    define('DEBUG_SQL_COMMENT_LONG', true); // Добавлять SQL запрос длинные комментарии. Не зависим от всех остальных параметров. Подойдет любое значение
1083
    define('DEBUG_SQL_COMMENT', true); // Добавлять комментарии прямо в SQL запрос. Подойдет любое значение
1084
    // Включаем нужные настройки
1085
    defined('DEBUG_SQL_ONLINE') && !defined('DEBUG_SQL_ERROR') ? define('DEBUG_SQL_ERROR', true) : false;
1086
    defined('DEBUG_SQL_ERROR') && !defined('DEBUG_SQL_COMMENT') ? define('DEBUG_SQL_COMMENT', true) : false;
1087
    defined('DEBUG_SQL_COMMENT_LONG') && !defined('DEBUG_SQL_COMMENT') ? define('DEBUG_SQL_COMMENT', true) : false;
1088
1089
    if (defined('BE_DEBUG') || static::$config->debug) {
1090
      @define('BE_DEBUG', true);
1091
      @ini_set('display_errors', 1);
1092
      @error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);
1093
    } else {
1094
      @define('BE_DEBUG', false);
1095
      @ini_set('display_errors', 0);
1096
    }
1097
1098
  }
1099
1100
  public static function checkReturnRef(&$ref1, &$ref2) {
1101
    if (isset($ref1['id'])) {
1102
      $ref1['id']++;
1103
      pdump($ref1['id']);
1104
      pdump($ref2['id']);
1105
      if ($ref2['id'] == $ref1['id']) {
1106
        pdump('ok');
1107
      } else {
1108
        pdie('failed');
1109
      }
1110
      $ref2['id']--;
1111
      if ($ref2['id'] == $ref1['id']) {
1112
        pdump('ok');
1113
      } else {
1114
        pdie('failed');
1115
      }
1116
    }
1117
1118
  }
1119
1120
}
1121