Completed
Push — work-fleets ( 04acf9...8f8df9 )
by SuperNova.WS
07:02
created

Account::db_mm_log_insert()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 15
c 1
b 0
f 0
nc 1
nop 4
dl 0
loc 19
rs 9.4285
ccs 0
cts 17
cp 0
crap 6
1
<?php
2
3
/**
4
 * Created by Gorlum 24.08.2015 6:00
5
 */
6
class Account {
7
  /**
8
   * @var int
9
   */
10
  public $account_id = 0;
11
  /**
12
   * @var string
13
   */
14
  public $account_name = '';
15
  /**
16
   * @var string
17
   */
18
  public $account_password = '';
19
  /**
20
   * @var string
21
   */
22
  public $account_salt = '';
23
  /**
24
   * @var string
25
   */
26
  public $account_email = '';
27
  /**
28
   * @var int
29
   */
30
  public $account_email_verified = 0;
31
  /**
32
   * @var string
33
   */
34
  public $account_register_time = '';
35
  /**
36
   * @var string
37
   */
38
  public $account_language = '';
39
40
  public $account_metamatter = 0;
41
  public $account_metamatter_total = 0;
42
43
  /**
44
   * @var int
45
   */
46
  public $is_exists = 0;
47
  /**
48
   * @var int
49
   */
50
  public $is_loaded = 0;
51
52
  /**
53
   * @var db_mysql
54
   */
55
  public $db;
56
57
  protected $table_check = array(
58
    'account'        => 'account',
59
    'log_metamatter' => 'log_metamatter',
60
  );
61
62
  public function reset() {
63
    $this->account_id = 0;
64
    $this->account_name = '';
65
    $this->account_password = '';
66
    $this->account_salt = '';
67
    $this->account_email = '';
68
    $this->account_email_verified = 0;
69
    $this->account_register_time = '';
70
    $this->account_language = '';
71
72
    $this->is_exists = 0;
73
    $this->is_loaded = 0;
74
  }
75
76
  public function __construct($db = null) {
77
    $this->reset();
78
    $this->db = is_object($db) ? $db : classSupernova::$db;
79
80
    foreach($this->table_check as $table_name) {
81
      if(empty($this->db->table_list[$table_name])) {
82
        die('Если вы видите это сообщение первый раз после обновления релиза - просто перегрузите страницу.<br />
83
              В противном случае - сообщите Администрации сервера об ошибке.<br/>
84
              Не хватает таблицы для работы системы авторизации: ' . $table_name);
85
      }
86
    }
87
  }
88
89
  // OK 4.5
90
  public function password_check($password_unsafe) {
91
    return $this->password_encode($password_unsafe, $this->account_salt) == $this->account_password;
92
  }
93
94
  /**
95
   * Меняет пароль у аккаунта в БД
96
   *
97
   * @param      $old_password_unsafe
98
   * @param      $new_password_unsafe
99
   * @param null $salt_unsafe
100
   *
101
   * @return bool
102
   */
103
  // OK v4.6
104
  public function password_change($old_password_unsafe, $new_password_unsafe, $salt_unsafe = null) {
105
    if(!$this->password_check($old_password_unsafe)) {
106
      return false;
107
    }
108
109
    $salt_unsafe === null ? $salt_unsafe = $this->password_salt_generate() : false;
110
    $result = $this->db_set_password($new_password_unsafe, $salt_unsafe);
111
112
    return $result;
113
  }
114
115
116
  /**
117
   * Заполняет поля объекта значениями результата запроса
118
   *
119
   * @param array $row
120
   *
121
   * @return bool
122
   */
123
  // OK v4.5
124
  public function assign_from_db_row($row) {
125
    $this->reset();
126
    if(empty($row) || !is_array($row)) {
127
      return false;
128
    }
129
    $this->account_id = $row['account_id'];
130
    $this->account_name = $row['account_name'];
131
    $this->account_password = $row['account_password'];
132
    $this->account_salt = $row['account_salt'];
133
    $this->account_email = $row['account_email'];
134
    $this->account_email_verified = $row['account_email_verified'];
135
    $this->account_register_time = $row['account_register_time'];
136
    $this->account_language = $row['account_language'];
137
138
    $this->account_metamatter = $row['account_metamatter'];
139
    $this->account_metamatter_total = $row['account_metamatter_total'];
140
141
    $this->is_exists = 1;
142
    $this->is_loaded = 1;
143
144
    return true;
145
  }
146
147
  /**
148
   * Возвращает аккаунт по его ID
149
   *
150
   * @param $account_id_unsafe
151
   *
152
   * @return bool
153
   */
154
  // OK v4.5
155
  public function db_get_by_id($account_id_unsafe) {
156
    $this->reset();
157
158
    $account_id_safe = round(floatval($account_id_unsafe));
159
160
    $account_row = $this->db->doSelectFetch("SELECT * FROM {{account}} WHERE `account_id` = {$account_id_safe}");
161
162
    return $this->assign_from_db_row($account_row);
163
  }
164
  /**
165
   * Возвращает аккаунт по имени
166
   *
167
   * @param string $account_name_safe
168
   *
169
   * @return bool
170
   */
171
  // OK v4.5
172
  public function db_get_by_name($account_name_unsafe) {
173
    $this->reset();
174
175
    $account_name_safe = $this->db->db_escape($account_name_unsafe);
176
177
    $account_row = $this->db->doSelectFetch("SELECT * FROM {{account}} WHERE LOWER(`account_name`) = LOWER('{$account_name_safe}') FOR UPDATE");
178
179
    return $this->assign_from_db_row($account_row);
180
  }
181
  /**
182
   * Возвращает аккаунт по емейлу
183
   *
184
   * @param string $email_unsafe
185
   *
186
   * @return bool
187
   */
188
  // OK v4.5
189
  public function db_get_by_email($email_unsafe) {
190
    $this->reset();
191
192
    $email_safe = $this->db->db_escape($email_unsafe);
193
194
    $account_row = $this->db->doSelectFetch("SELECT * FROM {{account}} WHERE LOWER(`account_email`) = LOWER('{$email_safe}') FOR UPDATE;");
195
196
    return $this->assign_from_db_row($account_row);
197
  }
198
  /**
199
   * Возвращает аккаунт по имени или аккаунту - проверка уникальных значений
200
   *
201
   * @param string $account_name_unsafe
202
   * @param string $email_unsafe
203
   *
204
   * @return bool
205
   *
206
   */
207
  // OK v4.5
208
  public function db_get_by_name_or_email($account_name_unsafe, $email_unsafe) {
209
    $this->reset();
210
211
    $account_name_safe = $this->db->db_escape($account_name_unsafe);
212
    $email_safe = $this->db->db_escape($email_unsafe);
213
214
    $account = $this->db->doSelectFetch(
215
      "SELECT * 
216
      FROM {{account}} 
217
      WHERE 
218
        LOWER(`account_name`) = LOWER('{$account_name_safe}') 
219
        OR 
220
        LOWER(`account_name`) = LOWER('{$email_safe}') 
221
        OR 
222
        LOWER(`account_email`) = LOWER('{$email_safe}') 
223
      FOR UPDATE"
224
    );
225
226
    return $this->assign_from_db_row($account);
227
  }
228
  /**
229
   * Создает аккаунт
230
   *
231
   * @throws Exception
232
   */
233
  // OK v4.5
234
  public function db_create($account_name_unsafe, $password_raw, $email_unsafe, $language_unsafe = null, $salt_unsafe = null) {
235
    $this->reset();
236
237
    $salt_unsafe === null ? $salt_unsafe = $this->password_salt_generate() : false;
238
    $password_salted_unsafe = $this->password_encode($password_raw, $salt_unsafe);
239
240
    $result = classSupernova::$db->doInsertSet(TABLE_ACCOUNT, array(
241
      'account_name'     => $account_name_unsafe,
242
      'account_password' => $password_salted_unsafe,
243
      'account_salt'     => $salt_unsafe,
244
      'account_email'    => strtolower($email_unsafe),
245
      'account_language' => $language_unsafe === null ? DEFAULT_LANG : $language_unsafe,
246
    ));
247
    if(!$result) {
248
      throw new Exception(REGISTER_ERROR_ACCOUNT_CREATE, ERR_ERROR);
249
    }
250
251
    if(!($account_id = $this->db->db_insert_id())) {
252
      throw new Exception(REGISTER_ERROR_ACCOUNT_CREATE, ERR_ERROR);
253
    }
254
255
    return $this->db_get_by_id($account_id);
256
  }
257
258
  /**
259
   * Физически меняет пароль аккаунта в БД
260
   *
261
   * @param string $password_unsafe
262
   * @param string $salt_unsafe
263
   *
264
   * @return bool
265
   */
266
  // OK v4.5
267
  public function db_set_password($password_unsafe, $salt_unsafe) {
268
    $password_encoded_unsafe = $this->password_encode($password_unsafe, $salt_unsafe);
269
    $password_encoded_safe = $this->db->db_escape($password_encoded_unsafe);
270
271
    $account_id_safe = $this->db->db_escape($this->account_id);
272
    $salt_safe = $this->db->db_escape($salt_unsafe);
273
274
    $result = $this->db->doUpdate(
275
      "UPDATE {{account}} SET
276
        `account_password` = '{$password_encoded_safe}',
277
        `account_salt` = '{$salt_safe}'
278
      WHERE `account_id` = '{$account_id_safe}'"
279
    ) ? true : false;
280
281
    if($result) {
282
      $result = $this->db_get_by_id($this->account_id);
283
    }
284
285
    return $result;
286
  }
287
288
289
290
  /**
291
   * Просаливает пароль
292
   *
293
   * @param $password
294
   * @param $salt
295
   *
296
   * @return string
297
   */
298
  // OK v4.5
299
  protected function password_encode($password, $salt) {
300
    return core_auth::password_encode($password, $salt);
301
  }
302
  /**
303
   * Генерирует соль
304
   *
305
   * @return string
306
   */
307
  // OK v4.5
308
  protected function password_salt_generate() {
309
    return core_auth::password_salt_generate();
310
  }
311
312
  /**
313
   * Вставляет запись об изменении количества ММ в лог ММ
314
   *
315
   * @param $comment
316
   * @param $change_type
317
   * @param $metamatter
318
   *
319
   * @return int|string
320
   */
321
  // OK 4.8
322
  protected function db_mm_log_insert($comment, $change_type, $metamatter, $user_id_unsafe) {
323
    $metamatter = round(floatval($metamatter));
324
325
    classSupernova::$db->doInsertSet(TABLE_LOG_METAMATTER, array(
326
      'provider_id'  => core_auth::$main_provider->provider_id,
327
      'account_id'   => $this->account_id,
328
      'account_name' => $this->account_name,
329
      'user_id'      => $user_id_unsafe,
330
      'username'     => !empty(core_auth::$user['username']) ? core_auth::$user['username'] : '',
331
      'reason'       => $change_type,
332
      'amount'       => $metamatter,
333
      'comment'      => $comment,
334
      'server_name'  => SN_ROOT_VIRTUAL,
335
      'page'         => $_SERVER['SCRIPT_NAME'],
336
    ));
337
    $result = $this->db->db_insert_id();
338
339
    return $result;
340
  }
341
342
  /**
343
   * @param int    $change_type
344
   * @param int    $metamatter
345
   * @param string $comment
346
   * @param bool   $already_changed
347
   *
348
   * @return array|bool|int|mysqli_result|null|string
349
   */
350
  public function metamatter_change($change_type, $metamatter, $comment = '', $already_changed = false) {
351
    global $mm_change_legit;
352
353
    if(!$this->is_exists || !($metamatter = round(floatval($metamatter)))) {
354
      classSupernova::$debug->error('Ошибка при попытке манипуляции с ММ');
355
356
      return false;
357
    }
358
359
    $account_id_safe = $this->db->db_escape($this->account_id);
360
361
    $mm_change_legit = true;
362
    // $sn_data_metamatter_db_name = pname_resource_name(RES_METAMATTER);
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% 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...
363
    if($already_changed) {
364
      $metamatter_total_delta = 0;
365
      $result = -1;
366
    } else {
367
      $metamatter_total_delta = $metamatter > 0 ? $metamatter : 0;
368
369
      $classConfig = classSupernova::$config;
370
      $result = $this->db->doUpdate(
371
        "UPDATE {{account}}
372
        SET
373
          `account_metamatter` = `account_metamatter` + '{$metamatter}'" .
374
        ($metamatter_total_delta ? ", `account_immortal` = IF(`account_metamatter_total` + '{$metamatter_total_delta}' >= {$classConfig->player_metamatter_immortal}, NOW(), `account_immortal`), `account_metamatter_total` = `account_metamatter_total` + '{$metamatter_total_delta}'" : '') .
375
        " WHERE `account_id` = {$account_id_safe}"
376
      );
377
      if(!$result) {
378
        classSupernova::$debug->error("Error adjusting Metamatter for player ID {$this->account_id} (Player Not Found?) with {$metamatter}. Reason: {$comment}", 'Metamatter Change', 402);
379
      }
380
      $result = classSupernova::$db->db_affected_rows();
381
    }
382
383
    if(empty(core_auth::$user['id'])) {
384
      $user_list = PlayerToAccountTranslate::db_translate_get_users_from_account_list(core_auth::$main_provider->provider_id, $this->account_id);
385
      reset($user_list);
386
      $user_id_unsafe = key($user_list);
387
    } else {
388
      $user_id_unsafe = core_auth::$user['id'];
389
    }
390
    $user_id_safe = $this->db->db_escape($user_id_unsafe);
391
392
    if(!$result) {
393
      classSupernova::$debug->error("Error adjusting Metamatter for player ID {$this->account_id} (Player Not Found?) with {$metamatter}. Reason: {$comment}", 'Metamatter Change', 402);
394
    }
395
396
    if(!$already_changed) {
397
      $this->account_metamatter += $metamatter;
398
      $this->account_metamatter_total += $metamatter_total_delta;
399
    }
400
401
    if(is_array($comment)) {
402
      $comment = call_user_func_array('sprintf', $comment);
403
    }
404
405
    $result = $this->db_mm_log_insert($comment, $change_type, $metamatter, $user_id_unsafe);
406
407
    if($metamatter > 0 && !empty($user_id_safe)) {
408
      $old_referral = db_referral_get_by_id($user_id_safe);
409 View Code Duplication
      if($old_referral['id']) {
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...
410
        $dark_matter_from_metamatter = $metamatter * AFFILIATE_MM_TO_REFERRAL_DM;
411
        db_referral_update_dm($user_id_safe, $dark_matter_from_metamatter);
412
        $new_referral = db_referral_get_by_id($user_id_safe);
413
414
        $partner_bonus = floor($new_referral['dark_matter'] / classSupernova::$config->rpg_bonus_divisor) - ($old_referral['dark_matter'] >= classSupernova::$config->rpg_bonus_minimum ? floor($old_referral['dark_matter'] / classSupernova::$config->rpg_bonus_divisor) : 0);
415
        if($partner_bonus > 0 && $new_referral['dark_matter'] >= classSupernova::$config->rpg_bonus_minimum) {
416
          rpg_points_change($new_referral['id_partner'], RPG_REFERRAL_BOUGHT_MM, $partner_bonus, "Incoming MM From Referral ID {$user_id_safe}");
417
        }
418
      }
419
    }
420
421
    $mm_change_legit = false;
422
423
    return $result;
424
  }
425
426
427
  // ------ UNUSED -----------------------------------------------------------------------------------------------------
428
429
}
430