Completed
Push — work-fleets ( 2bd11a...17dd3b )
by SuperNova.WS
06:36
created

sn_module_payment::db_insert()   B

Complexity

Conditions 7
Paths 48

Size

Total Lines 54
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 35
c 2
b 0
f 0
nc 48
nop 0
dl 0
loc 54
rs 7.8331
ccs 0
cts 37
cp 0
crap 56

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Created by Gorlum 21.04.2015 3:49
4
 */
5
6
abstract class sn_module_payment extends sn_module {
7
  public static $bonus_table = array(
8
    2000 => 0,
9
    // 5000 => 0,
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...
10
    10000 => 0,
11
    20000 => 0,
12
13
    50000 => 0.02,
14
    100000 => 0.05,
15
    200000 => 0.07,
16
    300000 => 0.10,
17
    400000 => 0.15,
18
    500000 => 0.20,
19
    800000 => 0.25,
20
    1000000 => 0.30,
21
    1500000 => 0.40,
22
    2000000 => 0.50,
23
    3000000 => 0.60,
24
    5000000 => 0.70,
25
  );
26
27
  public static $payment_methods = array(
28
    PAYMENT_METHOD_BANK_CARD => array(
29
      /*
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...
30
      PAYMENT_METHOD_id => array(
31
        'currency' => 'WMR', // Currency code 3 letter
32
        'image' => 'design/images/payments/emoney/webmoney.png', // Optional - image location from root. Setting image disables buttoning and name printing
33
        'name' => true, // Optional. Forces method name printing with 'image' set
34
        'button' => true, // Optional. Forces method buttoning with 'image' set
35
      ),
36
      */
37
      PAYMENT_METHOD_BANK_CARD_STANDARD => array(
38
        'currency' => 'RUB',
39
        'image' => 'design/images/payments/card/generic.png',
40
        'button' => true,
41
      ),
42
      PAYMENT_METHOD_BANK_CARD_LIQPAY => array(
43
        'currency' => 'UAH',
44
        'image' => 'design/images/payments/card/liqpay.png',
45
        'button' => true,
46
      ),
47
      PAYMENT_METHOD_BANK_CARD_EASYPAY => array(
48
        'currency' => 'UAH',
49
        'image' => 'design/images/payments/card/easypay.png',
50
        'button' => true,
51
      ),
52
      PAYMENT_METHOD_BANK_CARD_AMERICAN_EXPRESS => array(
53
        'currency' => 'USD',
54
        'image' => 'design/images/payments/card/american_express.png',
55
        'button' => true,
56
      ),
57
      PAYMENT_METHOD_BANK_CARD_JCB => array(
58
        'currency' => 'USD',
59
        'image' => 'design/images/payments/card/jcb.png',
60
        'button' => true,
61
      ),
62
      PAYMENT_METHOD_BANK_CARD_UNIONPAY => array(
63
        'currency' => 'USD',
64
        'image' => 'design/images/payments/card/unionpay.png',
65
        'button' => true,
66
      ),
67
    ),
68
69
    PAYMENT_METHOD_EMONEY => array(
70
      PAYMENT_METHOD_EMONEY_YANDEX => array(
71
        'currency' => 'RUB',
72
        'image' => 'design/images/payments/emoney/yandexmoney.png',
73
        'button' => true,
74
      ),
75
      PAYMENT_METHOD_EMONEY_QIWI => array(
76
        'currency' => 'RUB',
77
        'image' => 'design/images/payments/emoney/qiwi.png',
78
        'button' => true,
79
      ),
80
      PAYMENT_METHOD_EMONEY_PAYPAL => array(
81
        'currency' => 'RUB',
82
        'image' => 'design/images/payments/emoney/paypal.png',
83
        'button' => true,
84
      ),
85
      PAYMENT_METHOD_EMONEY_WEBMONEY_WMR => array(
86
        'currency' => 'WMR',
87
        'image' => 'design/images/payments/emoney/webmoney_wmr.gif',
88
        'button' => true,
89
      ),
90
      PAYMENT_METHOD_EMONEY_WEBMONEY_WMZ => array(
91
        'currency' => 'WMZ',
92
        'image' => 'design/images/payments/emoney/webmoney_wmz.gif',
93
        'button' => true,
94
      ),
95
      PAYMENT_METHOD_EMONEY_WEBMONEY_WMU => array(
96
        'currency' => 'WMU',
97
        'image' => 'design/images/payments/emoney/webmoney_wmu.gif',
98
        'button' => true,
99
      ),
100
      PAYMENT_METHOD_EMONEY_WEBMONEY_WME => array(
101
        'currency' => 'WME',
102
        'image' => 'design/images/payments/emoney/webmoney_wme.gif',
103
        'button' => true,
104
      ),
105
      PAYMENT_METHOD_EMONEY_WEBMONEY_WMB => array(
106
        'currency' => 'WMB',
107
        'image' => 'design/images/payments/emoney/webmoney_wmb.gif',
108
        'button' => true,
109
      ),
110
      PAYMENT_METHOD_EMONEY_TELEMONEY => array(
111
        'currency' => 'RUB',
112
        'image' => 'design/images/payments/emoney/telemoney.gif',
113
        'button' => true,
114
      ),
115
      PAYMENT_METHOD_EMONEY_ELECSNET => array(
116
        'currency' => 'RUB',
117
        'image' => 'design/images/payments/emoney/elecsnet.png',
118
        'button' => true,
119
      ),
120
      PAYMENT_METHOD_EMONEY_EASYPAY => array(
121
        'currency' => 'RUB',
122
        'image' => 'design/images/payments/emoney/easypay.png',
123
        'button' => true,
124
      ),
125
      PAYMENT_METHOD_EMONEY_RUR_W1R => array(
126
        'currency' => 'RUB',
127
        'image' => 'design/images/payments/emoney/walletone.png',
128
        'button' => true,
129
      ),
130
      PAYMENT_METHOD_EMONEY_MAILRU => array(
131
        'currency' => 'RUB',
132
        'image' => 'design/images/payments/emoney/mailru.gif',
133
      ),
134
    ),
135
136
    PAYMENT_METHOD_MOBILE => array(
137
      PAYMENT_METHOD_MOBILE_SMS => array(
138
        'currency' => 'RUB',
139
        'image' => 'design/images/payments/mobile/sms.png',
140
        'name' => true,
141
        'button' => true,
142
      ),
143
      PAYMENT_METHOD_MOBILE_PAYPAL_ZONG => array(
144
        'currency' => 'USD',
145
        'image' => 'design/images/payments/mobile/paypal_zong.png',
146
        'name' => true,
147
        'button' => true,
148
      ),
149
      PAYMENT_METHOD_MOBILE_XSOLLA => array(
150
        'currency' => 'RUB',
151
        'image' => 'design/images/payments/mobile/xsolla.png',
152
        'name' => true,
153
        'button' => true,
154
      ),
155
156
157
      PAYMENT_METHOD_MOBILE_MEGAPHONE => array(
158
        'currency' => 'RUB',
159
        'image' => 'design/images/payments/mobile/megafon.png',
160
        'button' => true,
161
      ),
162
      PAYMENT_METHOD_MOBILE_MTS => array(
163
        'currency' => 'RUB',
164
        'image' => 'design/images/payments/mobile/mts.png',
165
        'button' => true,
166
      ),
167
      PAYMENT_METHOD_MOBILE_KYIVSTAR => array(
168
        'currency' => 'UAH',
169
        'image' => 'design/images/payments/mobile/kyivstar.png',
170
        'button' => true,
171
      ),
172
    ),
173
174
    PAYMENT_METHOD_BANK_INTERNET => array(
175
      PAYMENT_METHOD_BANK_INTERNET_PRIVAT24 => array(
176
        'currency' => 'UAH',
177
        'image' => 'design/images/payments/bank_internet/privat24.png',
178
        'button' => true,
179
      ),
180
      PAYMENT_METHOD_BANK_INTERNET_BANK24 => array(
181
        'currency' => 'UAH',
182
        'image' => 'design/images/payments/bank_internet/bank24.png',
183
        'button' => true,
184
      ),
185
      PAYMENT_METHOD_BANK_INTERNET_ALFA_BANK => array(
186
        'currency' => 'RUB',
187
        'image' => 'design/images/payments/bank_internet/alfa_bank.png',
188
        'button' => true,
189
      ),
190
      PAYMENT_METHOD_BANK_INTERNET_SBERBANK => array(
191
        'currency' => 'RUB',
192
        'image' => 'design/images/payments/bank_internet/sberbank.png',
193
        'button' => true,
194
      ),
195
      PAYMENT_METHOD_BANK_INTERNET_PROSMVYAZBANK => array(
196
        'currency' => 'RUB',
197
        'image' => 'design/images/payments/bank_internet/prosmvyazbank.png',
198
        'button' => true,
199
      ),
200
      PAYMENT_METHOD_BANK_INTERNET_HANDY_BANK => array(
201
        'currency' => 'RUB',
202
        'image' => 'design/images/payments/bank_internet/handy_bank.png',
203
        'button' => true,
204
      ),
205
      PAYMENT_METHOD_BANK_INTERNET_RUSSKIY_STANDART => array(
206
        'currency' => 'RUB',
207
        'image' => 'design/images/payments/bank_internet/russkiy_standart.gif',
208
      ),
209
      PAYMENT_METHOD_BANK_INTERNET_VTB24 => array(
210
        'currency' => 'RUB',
211
        'image' => 'design/images/payments/bank_internet/vtb24.gif',
212
      ),
213
      PAYMENT_METHOD_BANK_INTERNET_OCEAN_BANK => array(
214
        'currency' => 'RUB',
215
        'image' => 'design/images/payments/bank_internet/ocean_bank.gif',
216
      ),
217
      PAYMENT_METHOD_BANK_INTERNET_007 => array(
218
        'currency' => 'RUB',
219
      ),
220
      PAYMENT_METHOD_BANK_INTERNET_008 => array(
221
        'currency' => 'RUB',
222
      ),
223
      PAYMENT_METHOD_BANK_INTERNET_009 => array(
224
        'currency' => 'RUB',
225
      ),
226
      PAYMENT_METHOD_BANK_INTERNET_010 => array(
227
        'currency' => 'RUB',
228
      ),
229
      PAYMENT_METHOD_BANK_INTERNET_011 => array(
230
        'currency' => 'RUB',
231
      ),
232
      PAYMENT_METHOD_BANK_INTERNET_012 => array(
233
        'currency' => 'RUB',
234
      ),
235
      PAYMENT_METHOD_BANK_INTERNET_013 => array(
236
        'currency' => 'RUB',
237
      ),
238
      PAYMENT_METHOD_BANK_INTERNET_014 => array(
239
        'currency' => 'RUB',
240
      ),
241
      PAYMENT_METHOD_BANK_INTERNET_015 => array(
242
        'currency' => 'RUB',
243
      ),
244
      PAYMENT_METHOD_BANK_INTERNET_016 => array(
245
        'currency' => 'RUB',
246
      ),
247
      PAYMENT_METHOD_BANK_INTERNET_017 => array(
248
        'currency' => 'RUB',
249
      ),
250
      PAYMENT_METHOD_BANK_INTERNET_018 => array(
251
        'currency' => 'RUB',
252
      ),
253
      PAYMENT_METHOD_BANK_INTERNET_019 => array(
254
        'currency' => 'RUB',
255
      ),
256
      PAYMENT_METHOD_BANK_INTERNET_020 => array(
257
        'currency' => 'RUB',
258
      ),
259
      PAYMENT_METHOD_BANK_INTERNET_021 => array(
260
        'currency' => 'RUB',
261
      ),
262
    ),
263
264
    PAYMENT_METHOD_BANK_TRANSFER => array(
265
    ),
266
267
    PAYMENT_METHOD_TERMINAL => array(
268
      PAYMENT_METHOD_TERMINAL_UKRAINE => array(
269
        'currency' => 'UAH',
270
        'image' => 'design/images/payments/terminal/ukraine.png',
271
        'button' => true,
272
        'name' => true,
273
      ),
274
      PAYMENT_METHOD_TERMINAL_IBOX => array(
275
        'currency' => 'UAH',
276
        'image' => 'design/images/payments/terminal/ibox.png',
277
        'button' => true,
278
      ),
279
      PAYMENT_METHOD_TERMINAL_EASYPAY => array(
280
        'currency' => 'UAH',
281
        'image' => 'design/images/payments/terminal/easypay.png',
282
        'button' => true,
283
      ),
284
      PAYMENT_METHOD_TERMINAL_RUSSIA => array(
285
        'currency' => 'RUB',
286
        'image' => 'design/images/payments/terminal/russia.png',
287
        'button' => true,
288
        'name' => true,
289
      ),
290
      PAYMENT_METHOD_TERMINAL_QIWI => array(
291
        'currency' => 'RUB',
292
        'image' => 'design/images/payments/terminal/qiwi.png',
293
        'button' => true,
294
      ),
295
      PAYMENT_METHOD_TERMINAL_ELECSNET => array(
296
        'currency' => 'RUB',
297
        'image' => 'design/images/payments/terminal/elecsnet.png',
298
        'button' => true,
299
      ),
300
      PAYMENT_METHOD_TERMINAL_TELEPAY => array(
301
        'currency' => 'RUB',
302
        'image' => 'design/images/payments/terminal/telepay.png',
303
        'button' => true,
304
      ),
305
      PAYMENT_METHOD_TERMINAL_ELEMENT => array(
306
        'currency' => 'RUB',
307
        'image' => 'design/images/payments/terminal/element.gif',
308
      ),
309
      PAYMENT_METHOD_TERMINAL_KASSIRANET => array(
310
        'currency' => 'RUB',
311
        'image' => 'design/images/payments/terminal/kassira_net.gif',
312
        'button' => true,
313
      ),
314
    ),
315
316
    PAYMENT_METHOD_OTHER => array(
317
      PAYMENT_METHOD_OTHER_EVROSET => array(
318
        'currency' => 'RUB',
319
        'image' => 'design/images/payments/other/evroset.gif',
320
      ),
321
      PAYMENT_METHOD_OTHER_SVYAZNOY => array(
322
        'currency' => 'RUB',
323
        'image' => 'design/images/payments/other/svyaznoy.gif',
324
      ),
325
      PAYMENT_METHOD_OTHER_ROBOKASSA_MOBILE => array(
326
        'currency' => 'RUB',
327
        'image' => 'design/images/payments/other/robokassa_mobile.gif',
328
        'name' => true,
329
      ),
330
    ),
331
332
    PAYMENT_METHOD_GENERIC => array(
333
      PAYMENT_METHOD_GENERIC_XSOLLA => array(
334
        'currency' => 'UAH',
335
        'image' => 'design/images/payments/generic/xsolla.png',
336
        'name' => true,
337
        'button' => true,
338
      ),
339
340
      PAYMENT_METHOD_GENERIC_ROBOKASSA => array(
341
        'currency' => 'RUB',
342
        'image' => 'design/images/payments/generic/robokassa.jpg',
343
        // 'name' => true,
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...
344
        'button' => true,
345
      ),
346
    ),
347
  );
348
349
  /**
350
   * @var Account $account
351
   */
352
  public $account = null;
353
354
  /**
355
   * @var db_mysql $db
356
   */
357
  public $db = null;
358
359
  /**
360
   * @var int
361
   */
362
  public $request_payment_id = 0;
363
  /**
364
   * Идентификатор сервера, на который производится оплата
365
   *
366
   * @var string $request_server_id
367
   */
368
  public $request_server_id = '';
369
  /**
370
   * Идентификатор платящего пользователя
371
   *
372
   * @var int
373
   */
374
  public $request_account_id = 0;
375
  /**
376
   * @var int
377
   */
378
  // public $request_mm_amount = 0;
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...
379
  /**
380
   * @var float
381
   */
382
  // public $request_money_out = 0.0;
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...
383
384
  /**
385
   * Внутренний идентификатор платежа
386
   *
387
   * @var int
388
   */
389
  public $payment_id = 0;
390
  public $payment_status = PAYMENT_STATUS_NONE;
391
  public $payment_provider_id = ACCOUNT_PROVIDER_NONE;
392
  public $payment_account_id = 0;
393
  public $payment_account_name = '';
394
  public $payment_user_id = 0;
395
  public $payment_user_name = '';
396
  public $payment_amount = 0;
397
  public $payment_currency = '';
398
  public $payment_dark_matter_paid = 0;
399
  public $payment_dark_matter_gained = 0;
400
  public $payment_date = SN_TIME_SQL;
401
  public $payment_comment = '';
402
  public $payment_module_name = '';
403
404
  public $payment_external_id = '';
405
  public $payment_external_date = '';
406
  public $payment_external_lots = 0;
407
  public $payment_external_amount = 0;
408
  public $payment_external_currency = '';
409
410
  public $payment_test = 0;
411
412
  public $is_exists = false;
413
  public $is_loaded = false;
414
415
  protected $description_generated = array();
416
417
  protected $debug = false;
418
419
  protected $payment_params = array(
420
//    'server_id' => 'shp_server', // Должен быть server_id
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...
421
//    'account_id' => 'shp_id', // Должен быть user_id
422
//    'payment_id' => 'InvId', // Должен быть внутренний payment_id
423
//    'payment_dark_matter_gained' => 'shp_dm', // TODO - Реально - dark_matter_gained! Что бы учитывались акции!
424
//    'payment_external_money' => 'OutSum', // Количество денег "к оплате" от СН
425
//    'test' => 'shp_z_test', // Тестовый статус аккаунта
426
//    'payment_external_id' => '', // ИД платежа в платёжной системе
427
//    'payment_external_currency' => 'payment_currency', // Валюта платежа в платёжной системе
428
  );
429
430
  protected $result_translations = array(
431
    // Универсальный ответ на неизвестную ошибку
432
    SN_PAYMENT_REQUEST_UNDEFINED_ERROR => SN_PAYMENT_REQUEST_UNDEFINED_ERROR,
433
    // Утвердительный ответ
434
    SN_PAYMENT_REQUEST_OK => SN_PAYMENT_REQUEST_OK,
435
  );
436
437
//  public function __construct($filename = __FILE__) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% 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...
438
//    parent::__construct($filename);
439
//  }
440
441
  /**
442
   * Компилирует запрос к платёжной системе
443
   *
444
   * @param $request
445
   *
446
   * @throws Exception
447
   */
448
  public function compile_request($request) {
449
    global $user;
450
451
    if(!(classSupernova::$auth->account instanceof Account)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if 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 if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
452
      // TODO - throw new Exception(lang['pay_msg_mm_request_amount_invalid'], SN_PAYMENT_REQUEST_ERROR_UNIT_AMOUNT);
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...
453
    }
454
    $this->account = classSupernova::$auth->account;
455
456
    $this->db = $this->account->db;
457
    // pdump($this->db);
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% 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...
458
459
    $this->payment_provider_id = core_auth::$main_provider->provider_id;
460
    $this->payment_account_id = $this->account->account_id;
461
    $this->payment_account_name = $this->account->account_name;
462
    $this->payment_user_id = $user['id'];
463
    $this->payment_user_name = $user['username'];
464
465
    // TODO - минимальное количество ММ к оплате
466
    $this->payment_dark_matter_paid = $request['metamatter'];
467
    $this->payment_dark_matter_gained = self::bonus_calculate($this->payment_dark_matter_paid, true);
0 ignored issues
show
Documentation Bug introduced by
It seems like self::bonus_calculate($t...dark_matter_paid, true) can also be of type double. However, the property $payment_dark_matter_gained is declared as type integer. 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...
468
469
    $this->payment_currency = classSupernova::$config->payment_currency_default;
470
    $this->payment_amount = self::currency_convert($this->payment_dark_matter_paid, 'MM_', $this->payment_currency);
0 ignored issues
show
Documentation Bug introduced by
It seems like self::currency_convert($...this->payment_currency) can also be of type double. However, the property $payment_amount is declared as type integer. 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...
471
472
    if(empty($this->payment_external_currency) && !empty($this->config['currency'])) {
473
      $this->payment_external_currency = $this->config['currency'];
474
    }
475
    if(empty($this->payment_external_currency)) {
476
      throw new Exception(classLocale::$lang['pay_error_internal_no_external_currency_set'], SN_PAYMENT_ERROR_INTERNAL_NO_EXTERNAL_CURRENCY_SET);
477
    }
478
479
    $this->payment_external_amount = self::currency_convert($this->payment_dark_matter_paid, 'MM_', $this->payment_external_currency);
0 ignored issues
show
Documentation Bug introduced by
It seems like self::currency_convert($...ment_external_currency) can also be of type double. However, the property $payment_external_amount is declared as type integer. 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...
480
    if($this->payment_external_amount < 0.01) {
481
      throw new Exception(classLocale::$lang['pay_msg_mm_request_amount_invalid'], SN_PAYMENT_REQUEST_ERROR_UNIT_AMOUNT);
482
    }
483
484
    $this->payment_test = !empty($this->config['test']);
0 ignored issues
show
Documentation Bug introduced by
The property $payment_test was declared of type integer, but !empty($this->config['test']) is of type boolean. 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...
485
486
    $this->generate_description();
487
488
    $this->db_insert();
489
    if(!$this->is_exists) {
490
      throw new Exception(classLocale::$lang['pay_msg_request_error_db_payment_create'], SN_PAYMENT_REQUEST_DB_ERROR_PAYMENT_CREATE);
491
    }
492
  }
493
494
  /**
495
   * @param array $options
496
   *
497
   * @return array
498
   * @throws Exception
499
   */
500
  protected function payment_request_process($options = array()) {
501
    if(!$this->manifest['active']) {
502
      throw new Exception(classLocale::$lang['pay_msg_module_disabled'], SN_MODULE_DISABLED);
503
    }
504
505
    // Если есть payment_id - загружаем под него данные
506
    if(!empty($this->payment_params['payment_id'])) {
507
      $this->request_payment_id = sys_get_param_id($this->payment_params['payment_id']);
0 ignored issues
show
Documentation Bug introduced by
It seems like sys_get_param_id($this->...t_params['payment_id']) can also be of type string or array. However, the property $request_payment_id is declared as type integer. 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...
508
      if(!$this->request_payment_id) {
509
        throw new Exception(classLocale::$lang['pay_msg_request_payment_id_invalid'], SN_PAYMENT_REQUEST_INTERNAL_ID_WRONG);
510
      }
511
512
      if(!$this->db_get_by_id($this->request_payment_id)) {
513
        throw new Exception(classLocale::$lang['pay_msg_request_payment_id_invalid'], SN_PAYMENT_REQUEST_INTERNAL_ID_WRONG);
514
      }
515
516
      // Проверяем - был ли этот платеж обработан?
517
      // TODO - Статусы бывают разные. Нужен спецфлаг payment_processed
518
      if($this->payment_status != PAYMENT_STATUS_NONE) {
519
        sn_db_transaction_rollback();
520
        sys_redirect(SN_ROOT_VIRTUAL . 'metamatter.php?payment_id=' . $this->payment_id);
521
        die();
522
      }
523
    }
524
525
    // Пытаемся получить из запроса ИД аккаунта
526
    $request_account_id = !empty($this->payment_params['account_id']) ? sys_get_param_id($this->payment_params['account_id']) : 0;
527
    // Если в запросе нет ИД аккаунта - пытаемся использовать payment_account_id
528
    if(empty($request_account_id) && !empty($this->payment_account_id)) {
529
      $request_account_id = $this->payment_account_id;
530
    }
531
    // Если теперь у нас нету ИД аккаунта ни в запросе, ни в записи таблицы - можно паниковать
532
    if(empty($request_account_id)) {
533
      // TODO - аккаунт
534
      throw new Exception(classLocale::$lang['pay_msg_request_user_invalid'], $this->retranslate_error(SN_PAYMENT_REQUEST_USER_NOT_FOUND, $options));
535
    }
536
    // Если нет записи в таблице - тогда берем payment_account_id из запроса
537
    if(empty($this->payment_account_id)) {
538
      $this->payment_account_id = $request_account_id;
0 ignored issues
show
Documentation Bug introduced by
It seems like $request_account_id can also be of type string or array. However, the property $payment_account_id is declared as type integer. 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...
539
    }
540
    // Если у нас отличаются ИД аккаунта в запросе и ИД аккаунта в записи - тоже можно паниковать
541
    if($this->payment_account_id != $request_account_id) {
542
      // TODO - Поменять сообщение об ошибке
543
      throw new Exception(classLocale::$lang['pay_msg_request_user_invalid'], $this->retranslate_error(SN_PAYMENT_REQUEST_USER_NOT_FOUND, $options));
544
    }
545
    // Проверяем существование аккаунта с данным ИД
546
    if(!$this->account->db_get_by_id($this->payment_account_id)) {
547
      throw new Exception(classLocale::$lang['pay_msg_request_user_invalid'] . ' ID ' . $this->payment_account_id, $this->retranslate_error(SN_PAYMENT_REQUEST_USER_NOT_FOUND, $options));
548
    }
549
550
    // TODO Проверка на сервер_ид - как бы и не нужна, наверное?
551
    if(!empty($this->payment_params['server_id'])) {
552
      $this->request_server_id = sys_get_param_str($this->payment_params['server_id']);
553
      if(SN_ROOT_VIRTUAL != $this->request_server_id) {
554
        throw new Exception(classLocale::$lang['pay_msg_request_server_wrong'] . " {$this->request_server_id} вместо " . SN_ROOT_VIRTUAL, SN_PAYMENT_REQUEST_SERVER_WRONG);
555
      }
556
    }
557
558
    // Сверка количества оплаченной ММ с учётом бонусов
559 View Code Duplication
    if(!empty($this->payment_params['payment_dark_matter_gained'])) {
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...
560
      $request_mm_amount = sys_get_param_id($this->payment_params['payment_dark_matter_gained']);
561
      if($request_mm_amount != $this->payment_dark_matter_gained && $this->is_loaded) {
562
        throw new Exception(classLocale::$lang['pay_msg_mm_request_amount_invalid'] . " пришло {$request_mm_amount} ММ вместо {$this->payment_dark_matter_gained} ММ", SN_PAYMENT_REQUEST_MM_AMOUNT_INVALID);
563
      }
564
      empty($this->payment_dark_matter_gained) ? $this->payment_dark_matter_gained = $request_mm_amount : false;
0 ignored issues
show
Documentation Bug introduced by
It seems like $request_mm_amount can also be of type string or array. However, the property $payment_dark_matter_gained is declared as type integer. 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...
565
    }
566
    if(empty($this->payment_dark_matter_paid)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if 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 if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
567
      // TODO - обратный расчёт из gained
568
    }
569
570
    // Проверка наличия внешнего ИД платежа
571
    if(!empty($this->payment_params['payment_external_id'])) {
572
      $request_payment_external_id = sys_get_param_id($this->payment_params['payment_external_id']);
573
      if(empty($request_payment_external_id)) {
574
        throw new exception(classLocale::$lang['pay_msg_request_payment_id_invalid'], SN_PAYMENT_REQUEST_EXTERNAL_ID_WRONG);
575
      } elseif(!empty($this->payment_external_id) && $this->payment_external_id != $request_payment_external_id) {
576
        // TODO - Может быть поменять сообщение
577
        throw new exception(classLocale::$lang['pay_msg_request_payment_id_invalid'], SN_PAYMENT_REQUEST_EXTERNAL_ID_WRONG);
578
      }
579
      $this->payment_external_id = $request_payment_external_id;
0 ignored issues
show
Documentation Bug introduced by
It seems like $request_payment_external_id can also be of type array or integer. However, the property $payment_external_id is declared as type string. 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...
580
    }
581
    // Сверка суммы, запрошенной СН к оплате
582 View Code Duplication
    if(!empty($this->payment_params['payment_external_money'])) {
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...
583
      $request_money_out = sys_get_param_float($this->payment_params['payment_external_money']);
584
      if($request_money_out != $this->payment_external_amount && $this->is_loaded) {
585
        throw new Exception(classLocale::$lang['pay_msg_request_payment_amount_invalid'] . " пришло {$request_money_out} денег вместо {$this->payment_external_amount} денег", SN_PAYMENT_REQUEST_CURRENCY_AMOUNT_INVALID);
586
      }
587
      empty($this->payment_external_amount) ? $this->payment_external_amount = $request_money_out : false;
0 ignored issues
show
Documentation Bug introduced by
The property $payment_external_amount was declared of type integer, but $request_money_out is of type double. 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...
588
    }
589
    // Заполняем поле валюты платёжной системы
590
    if(!empty($this->payment_params['payment_external_currency'])) {
591
      $this->payment_external_currency = sys_get_param_str($this->payment_params['payment_external_currency']);
592
      if(empty($this->payment_external_currency)) {
593
        // TODO - поменять сообщение
594
        throw new Exception(classLocale::$lang['pay_msg_request_payment_amount_invalid'] . " {$this->payment_external_currency}", SN_PAYMENT_REQUEST_CURRENCY_AMOUNT_INVALID);
595
      }
596
    }
597
    if(empty($this->payment_external_currency)) {
598
      $this->payment_external_currency = $this->config['currency'];
599
    }
600
601
    // Заполнение внутренней суммы и валюты из внешних данных
602
    if(empty($this->payment_currency)) {
603
      $this->payment_currency = classSupernova::$config->payment_currency_default;
604
    }
605
    if(empty($this->payment_amount) && !empty($this->payment_external_currency)) {
606
      $this->payment_amount = self::currency_convert($this->payment_external_amount, $this->payment_external_currency, $this->payment_currency);
0 ignored issues
show
Documentation Bug introduced by
It seems like self::currency_convert($...this->payment_currency) can also be of type double. However, the property $payment_amount is declared as type integer. 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...
607
    }
608
609
    // TODO - Тестовый режим
610
    if(!empty($this->payment_params['test'])) {
611
      $this->payment_test = $this->config['test'] || sys_get_param_int($this->payment_params['test']);
0 ignored issues
show
Documentation Bug introduced by
The property $payment_test was declared of type integer, but $this->config['test'] ||...payment_params['test']) is of type boolean. 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...
612
    }
613
614
    $this->generate_description();
615
616
//    // TODO - REMOVE
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...
617
//    return array(
618
//      'payer' => $this->account,
619
//    );
620
  }
621
622
  /**
623
   * Точка входа для коллбэка системы платежей - вызывается из <class_name>_response.php
624
   *
625
   * @return array
626
   */
627
  // OK 4.8
628
  // TODO - Здесь должно происходить разделение на resultURL, successURL, failURL
629
  public function payment_request_response() {
630
    $this->db = core_auth::$main_provider->db;
631
    $this->account = new Account($this->db);
632
633
    // TODO - REPLACE WITH INNATE CALL!
634
    sn_db_transaction_start();
635
    try {
636
      $response = $this->payment_request_process();
637
    } catch(Exception $e) {
638
      $response['result'] = $e->getCode();
639
      $response['message'] = $e->getMessage();
640
    }
641
642
    if($response['result'] == SN_PAYMENT_REQUEST_OK) {
643
      sn_db_transaction_commit();
644
      classSupernova::$debug->warning('Результат операции: код ' . $response['result'] . ' сообщение "' . $response['message'] . '"', 'Успешный платёж', LOG_INFO_PAYMENT);
645
    } else {
646
      sn_db_transaction_rollback();
647
      classSupernova::$debug->warning('Результат операции: код ' . $response['result'] . ' сообщение "' . $response['message'] . '"', 'Ошибка платежа', LOG_INFO_PAYMENT, true);
648
    }
649
650
    // Переводим код результата из СН в код платежной системы
651
    if(is_array($this->result_translations) && !empty($this->result_translations)) {
652
      $response['result'] = isset($this->result_translations[$response['result']]) ? $this->result_translations[$response['result']] : $this->result_translations[SN_PAYMENT_REQUEST_UNDEFINED_ERROR];
653
    }
654
655
    return $response;
656
  }
657
658
659
  // Function converts money values between currencies
660
  /**
661
   * Внутриигровая конвертация валют
662
   *
663
   * @param        $value
664
   * @param string $currency_from
665
   * @param string $currency_to
666
   * @param int    $round
667
   *
668
   * @return float|int
669
   */
670
  public static function currency_convert($value, $currency_from = '', $currency_to = '', $round = 2) {
671
    $currency_from = strtolower($currency_from);
672
    $currency_to = strtolower($currency_to);
673
674
    if($currency_from != $currency_to) {
675
      $exchange_from = get_exchange_rate($currency_from);
676
      $exchange_to = get_exchange_rate($currency_to);
677
678
      $value = $exchange_from ? $value / $exchange_from * $exchange_to * pow(10, $round) : 0;
679
      $value = ceil($value) / pow(10, $round);
680
    }
681
682
    return $value;
683
  }
684
685
  // Function calculates bonused DM amount for bulk purchase and ($direct = false) vice versa
686
  /**
687
   * Рассчёт бонуса ММ
688
   *
689
   * @param            $dark_matter
690
   * @param bool|true  $direct
691
   * @param bool|false $return_bonus
692
   *
693
   * @return float|int
694
   */
695
  public static function bonus_calculate($dark_matter, $direct = true, $return_bonus = false) {
696
    $bonus = 0;
697
    $dark_matter_new = $dark_matter;
698
    if(!empty(self::$bonus_table) && $dark_matter >= self::$bonus_table[0]) {
699
      if($direct) {
700
        foreach(self::$bonus_table as $dm_for_bonus => $multiplier) {
701 View Code Duplication
          if($dm_for_bonus <= $dark_matter) {
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...
702
            $dark_matter_new = $dark_matter * (1 + $multiplier);
703
            $bonus = $multiplier;
704
          } else {
705
            break;
706
          }
707
        }
708
      } else {
709
        foreach(self::$bonus_table as $dm_for_bonus => $multiplier) {
710
          $temp = $dm_for_bonus * (1 + $multiplier);
711 View Code Duplication
          if($dark_matter >= $temp) {
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...
712
            $dark_matter_new = round($dark_matter / (1 + $multiplier));
713
            $bonus = $multiplier;
714
          } else {
715
            break;
716
          }
717
        }
718
      }
719
    }
720
721
    return $return_bonus ? $bonus : $dark_matter_new;
722
  }
723
724
  // Дополнительная ре-трансляция адреса, если в каком-то случае платежная система ожидает нелогичный ответ
725
  // Пример: иксолла при неправильно заданном пользователе в ордере ожидает НЕПРАВИЛЬНЫЙ_ОРДЕР, а не НЕПРАВИЛЬНЫЙ_ПОЛЬЗОВАТЕЛЬ
726
  public function retranslate_error($error_code, $options = array()) {
727
    return isset($options['retranslate_error'][$error_code]) ? $options['retranslate_error'][$error_code] : $error_code;
728
  }
729
730
731
  public function db_insert() {
732
    $this->payment_test = !empty($this->config['test']) || $this->payment_test;
0 ignored issues
show
Documentation Bug introduced by
The property $payment_test was declared of type integer, but !empty($this->config['te... || $this->payment_test is of type boolean. 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...
733
734
    $payment = array(
735
      'payment_module_name' => $this->manifest['name'],
736
737
      'payment_status' => $this->payment_status,
738
      // 'payment_date' => $this->payment_date, // Не нужно
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...
739
740
      'payment_provider_id' => $this->payment_provider_id,
741
      'payment_account_id' => $this->payment_account_id,
742
      'payment_account_name' => $this->payment_account_name,
743
      'payment_user_id' => $this->payment_user_id,
744
      'payment_user_name' => $this->payment_user_name,
745
746
      'payment_dark_matter_paid' => $this->payment_dark_matter_paid,
747
      'payment_dark_matter_gained' => $this->payment_dark_matter_gained,
748
749
      'payment_amount' => $this->payment_amount,
750
      'payment_currency' => $this->payment_currency,
751
752
      'payment_external_id' => $this->payment_external_id, // TODO
753
      'payment_external_amount' => $this->payment_external_amount,
754
      'payment_external_currency' => $this->payment_external_currency,
755
      'payment_external_date' => $this->payment_external_date, // TODO
756
757
      'payment_test' => $this->payment_test ? 1 : 0, // Boolean -> int
758
759
      'payment_comment' => $this->description_generated[PAYMENT_DESCRIPTION_MAX],
760
761
      'payment_external_lots' => $this->payment_dark_matter_paid / get_mm_cost(),
762
    );
763
764
    $replace = false;
765
    if($this->payment_id) {
766
      $payment['payment_id'] = $this->payment_id;
767
      $replace = true;
768
    }
769
770
    $query = array();
771
    foreach($payment as $key => $value) {
772
      $value = is_string($value) ? '"' . db_escape($value) . '"' : $value;
773
      $query[] = "`{$key}` = {$value}";
774
    }
775
776
    $longQuery = ' INTO `{{payment}}` SET ' . implode(',', $query) . ';';
777
    if($replace) {
778
      $this->db->doReplace('REPLACE' . $longQuery);
779
    } else {
780
      $this->db->doInsert('INSERT' . $longQuery);
781
    }
782
783
    return $this->db_get_by_id($this->db->db_insert_id());
784
  }
785
786
787
  public function payment_adjust_mm_new() {
788
    if(!$this->payment_test) {
789
      // Not a test payment. Adding DM to account
790
      $this->account = new Account($this->db);
791
      $this->account->db_get_by_id($this->payment_account_id);
792
      $result = $this->account->metamatter_change(RPG_PURCHASE, $this->payment_dark_matter_gained, $this->payment_comment);
793
      if(!$result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type false|integer is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
794
        throw new Exception('Ошибка начисления ММ', SN_METAMATTER_ERROR_ADJUST);
795
      }
796
    }
797
  }
798
799
  public function payment_cancel(&$payment) {
0 ignored issues
show
Unused Code introduced by
The parameter $payment 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...
800
    die('{НЕ РАБОТАЕТ! СООБЩИТЕ АДМИНИСТРАЦИИ!}');
801
802
    if(!isset($payment['payment_status'])) {
0 ignored issues
show
Unused Code introduced by
if (!isset($payment['pay...EST_ORDER_NOT_FOUND); } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
803
      throw new exception(classLocale::$lang['pay_msg_request_payment_not_found'], SN_PAYMENT_REQUEST_ORDER_NOT_FOUND);
804
    }
805
806
    if($payment['payment_status'] == PAYMENT_STATUS_COMPLETE) {
807
      $safe_comment = db_escape($payment['payment_comment'] = classLocale::$lang['pay_msg_request_payment_cancelled'] .' ' . $payment['payment_comment']);
808
809
      if(!$payment['payment_test']) {
810
        $result = $this->account->metamatter_change(RPG_PURCHASE_CANCEL, -$payment['payment_dark_matter_gained'], $payment['payment_comment']);
811
        if(!$result) {
812
          throw new exception('Ошибка начисления ММ', SN_METAMATTER_ERROR_ADJUST);
813
        }
814
      }
815
      $payment['payment_status'] = PAYMENT_STATUS_CANCELED;
816
      db_payment_update($payment, $safe_comment);
817
      throw new exception(classLocale::$lang['pay_msg_request_payment_cancel_complete'], SN_PAYMENT_REQUEST_OK);
818
    } elseif($payment['payment_status'] == PAYMENT_STATUS_CANCELED) {
819
      throw new exception(classLocale::$lang['pay_msg_request_payment_cancelled_already'], SN_PAYMENT_REQUEST_OK);
820
    } elseif($payment['payment_status'] == PAYMENT_STATUS_NONE) {
821
      throw new exception(classLocale::$lang['pay_msg_request_payment_cancel_not_complete'], SN_PAYMENT_REQUEST_PAYMENT_NOT_COMPLETE);
822
    }
823
  }
824
825
826
  protected function db_get_by_id($payment_id_unsafe) {
827
    $payment_id_internal_safe = $this->db->db_escape($payment_id_unsafe);
828
    $payment = $this->db->doSelectFetch(
829
      "SELECT * 
830
      FROM {{payment}} 
831
      WHERE 
832
        `payment_module_name` = '{$this->manifest['name']}' 
833
        AND 
834
        `payment_id` = '{$payment_id_internal_safe}' 
835
      LIMIT 1 
836
      FOR UPDATE;"
837
    );
838
    return $this->db_assign_payment($payment);
839
  }
840
841
  protected function db_complete_payment() {
842
    // TODO - поле payment_processed
843
    if($this->payment_status == PAYMENT_STATUS_NONE) {
844
      if(!defined('PAYMENT_EXPIRE_TIME') || PAYMENT_EXPIRE_TIME == 0 || empty($this->payment_date) || strtotime($this->payment_date) + PAYMENT_EXPIRE_TIME <= SN_TIME_NOW) {
845
        $this->payment_adjust_mm_new();
846
        $this->payment_status = PAYMENT_STATUS_COMPLETE;
847
      } else {
848
        $this->payment_status = PAYMENT_STATUS_EXPIRED;
849
      }
850
851
      $this->db_insert();
852
    }
853
  }
854
855
  protected function payment_reset() {
856
    $this->payment_id = 0;
857
    $this->payment_status = PAYMENT_STATUS_NONE;
858
859
    $this->payment_provider_id = ACCOUNT_PROVIDER_NONE;
860
    $this->payment_account_id = 0;
861
    $this->payment_account_name = '';
862
    $this->payment_user_id = 0;
863
    $this->payment_user_name = '';
864
865
    $this->payment_amount = 0;
866
    $this->payment_currency = '';
867
868
    $this->payment_dark_matter_paid = 0;
869
    $this->payment_dark_matter_gained = 0;
870
    $this->payment_date = SN_TIME_SQL;
871
    $this->payment_comment = '';
872
    $this->payment_module_name = '';
873
874
    $this->payment_external_id = '';
875
    $this->payment_external_date = '';
876
    $this->payment_external_lots = 0;
877
    $this->payment_external_amount = 0;
878
    $this->payment_external_currency = '';
879
880
    $this->payment_test = 0;
881
882
    $this->is_exists = false;
883
    $this->is_loaded = false;
884
885
    $this->description_generated = array();
886
  }
887
888
  protected function db_assign_payment($payment = null) {
889
    $this->payment_reset();
890
891
    if(is_array($payment) && isset($payment['payment_id'])) {
892
      $this->payment_id = $payment['payment_id'];
893
      $this->payment_status = $payment['payment_status'];
894
      $this->payment_date = $payment['payment_date'];
895
896
      $this->payment_provider_id = $payment['payment_provider_id'];
897
      $this->payment_account_id = $payment['payment_account_id'];
898
      $this->payment_account_name = $payment['payment_account_name'];
899
      $this->payment_user_id = $payment['payment_user_id'];
900
      $this->payment_user_name = $payment['payment_user_name'];
901
902
      $this->payment_amount = $payment['payment_amount'];
903
      $this->payment_currency = $payment['payment_currency'];
904
905
      $this->payment_dark_matter_paid = $payment['payment_dark_matter_paid'];
906
      $this->payment_dark_matter_gained = $payment['payment_dark_matter_gained'];
907
908
      $this->payment_comment = $payment['payment_comment'];
909
      $this->payment_module_name = $payment['payment_module_name'];
910
911
      $this->payment_external_id = $payment['payment_external_id'];
912
      $this->payment_external_date = $payment['payment_external_date'];
913
      $this->payment_external_lots = $payment['payment_external_lots'];
914
      $this->payment_external_amount = $payment['payment_external_amount'];
915
      $this->payment_external_currency = $payment['payment_external_currency'];
916
917
      $this->payment_test = $payment['payment_test'];
918
919
      $this->is_exists = true;
920
      $this->is_loaded = true;
921
922
      $this->generate_description();
923
924
      return true;
925
    } else {
926
      return false;
927
    }
928
  }
929
930
  protected function generate_description() {
931
    // TODO - системная локализация
932
    $this->description_generated = array(
933
      PAYMENT_DESCRIPTION_100 => substr("{$this->payment_dark_matter_gained} ММ аккаунт [{$this->account->account_name}] ID {$this->account->account_id} на " . SN_ROOT_VIRTUAL, 0, 100),
934
      PAYMENT_DESCRIPTION_250 => substr("Оплата {$this->payment_dark_matter_gained} ММ для аккаунта [{$this->payment_user_name}] ID {$this->payment_user_id} на сервере " . SN_ROOT_VIRTUAL, 0, 250),
935
      PAYMENT_DESCRIPTION_MAX => ($this->payment_test ? "ТЕСТОВЫЙ ПЛАТЕЖ! " : '') .
936
        "Платеж от аккаунта '{$this->payment_account_name}' ID {$this->payment_account_id} игрока '{$this->payment_user_name}' ID {$this->payment_user_id} на сервере " . SN_ROOT_VIRTUAL .
937
        " сумма {$this->payment_amount} {$this->payment_currency} за {$this->payment_dark_matter_paid} ММ (начислено {$this->payment_dark_matter_gained} ММ)" .
938
        " через '{$this->manifest['name']}' сумма {$this->payment_external_amount} {$this->payment_external_currency}",
939
    );
940
  }
941
942
}
943